john smith
john smith

Reputation: 85

Could not cast value of type 'NSNull' to 'NSDictionary'

I am getting an error that in the line "self.email = (snapshot.value as! NSDictionary)["email"] as! String" saying that it could not cast value of type 'NSNull'. How do I fix the error? I thought that since I have a function toAnyObject that it would convert everything to a String.

struct User {
    var email: String!
    var uid: String!
    var ref: DatabaseReference!
    var key: String = ""

    init(snapshot: DataSnapshot) {
        self.email = (snapshot.value as! NSDictionary)["email"] as! String
        self.uid = (snapshot.value as! NSDictionary)["uid"] as! String
        self.ref = snapshot.ref
        self.key = snapshot.key
    }

    init(email: String, uid: String) {
        self.email = email
        self.uid = uid
        self.ref = Database.database().reference()
    }

    func toAnyObject() -> [String: Any] {
        return ["email":self.email, "uid":self.uid]
    }
}

Upvotes: 0

Views: 4165

Answers (2)

Ishika
Ishika

Reputation: 2205

    struct User {

    var email: String!
    var uid: String!
    var ref: DatabaseReference!
    var key: String = ""

    init(snapshot: DataSnapshot){

        self.email = (snapshot.value as! NSDictionary)["email"] as! String
        self.uid = (snapshot.value as! NSDictionary)["uid"] as! String
        self.ref = snapshot.ref
        self.key = snapshot.key

    }

    init(email: String, uid: String){

        if let snap = snapshot.value as? [String:Any] {
        // Do not unwrap forcefully, instead use as mentioned below 
        // so that in case snap["email"] gives null that could be 
        //handled. 
        //Also please check that whether you have "firstname" var 
        //present in not in your code and dictionary both. 
        self.email = snap["email"] as? String ?? "" //Provide some default value or empty string
        }
        self.uid = uid
        self.ref = Database.database().reference()

    }

    func toAnyObject() -> [String: Any]{
        return ["email":self.email, "uid":self.uid]
    }
    }

Upvotes: 0

Rashwan L
Rashwan L

Reputation: 38843

As El Captain v2.0 pointed out, don´t force unwrap a value as it might be nil and you´ll get a crash. Use if let instead:

// if snap has a value, then you can use the value. Otherwise not, you can call an else if you want to.
if let snap = snapshot.value as? [String:Any] { 
    self.email = snap["email"] as! String 
}

And I would skip the as! String too and would have done it like this instead, incase of you don´t get the email value.

if let snap = snapshot.value as? [String:Any], let email = snap["email"] as? String  { 
    // Use email in here now
    print(email)
}

So if you have other fields you want to get, just add them into the if-statement.

Upvotes: 6

Related Questions