Cowboy
Cowboy

Reputation: 49

Firebase Swift 3.0 setValuesForKeysWithDictionary

Here is the code:

func observeMessages() {

    let ref = FIRDatabase.database().reference().child("messages")
    ref.observe(.childAdded, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {
            let message = Message()
            message.setValuesForKeys(dictionary)
            self.messages.append(message)
            //this will crash because of background thread, so lets call this on dispatch_async main thread
            DispatchQueue.main.async(execute: {
                self.tableView.reloadData()
            })
        } 
        }, withCancel: nil)

}

When run, it crashes like this:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'

Please kindly help me fix this.

Upvotes: 4

Views: 1571

Answers (1)

Herakleis
Herakleis

Reputation: 533

The problem is that there is a mismatch between your Message model class and what you are trying to put inside of your instance of it through the setValuesForKeys method. Your dictionary does not line up with the Message class.

This is what the error message tells you: your app tried to set a value for a key from your snapshot.value that does not exist in your Message class.

Check that there is exactly the same number of properties with the same name in your Message class as in your snapshot.value.

To avoid mismatches, you could define your Message class as such:

class Message: NSObject {

    var fromId: String?
    var text: String?
    var timestamp: NSNumber?
    var toId: String?
    var imageUrl: String?
    var imageWidth: NSNumber?
    var imageHeight: NSNumber?

    init(dictionary: [String: AnyObject]) {

        super.init()
        fromId = dictionary["fromId"] as? String
        text = dictionary["text"] as? String
        timestamp = dictionary["timestamp"] as? NSNumber
        toId = dictionary["toId"] as? String
        imageUrl = dictionary["imageUrl"] as? String
        imageWidth = dictionary["imageWidth"] as? NSNumber
        imageHeight = dictionary["imageHeight"] as? NSNumber
    }

}

Upvotes: 3

Related Questions