You can't trust print to reveal the types of the values in the dictionary. Consider this example:
var user1: NSMutableDictionary = [
"id1" : "1",
"id2" : 2,
"id3" : 3.141592654
]
for (key, value) in user1 {
var type: String
switch value {
case let i as NSNumber:
type = "NSNumber"
case let s as NSString:
type = "NSString"
default:
type = "something else"
}
print("\(key) is \(type)")
}
id1 is NSString
id2 is NSNumber
id3 is NSNumber
print(user1)
{
id1 = 1;
id2 = 2;
id3 = "3.141592654";
}
Note that id1 is a NSString and id2 is an NSNumber and neither has quotation marks "". id3 which is an NSNumber has quotation marks.
Because (user["id"] as? Int)! gives the error:
Could not cast value of type '__NSCFString' (0x24807ac) to 'NSNumber'
(0x28d96dc)
the underlying type is NSString which will need to be converted to Int after conditionally casting them to String:
For Swift 1.2:
self.id = (user["id"] as? String)?.toInt() ?? 0
self.accStatus = (user["accStatus"] as? String)?.toInt() ?? 0
self.accessKey = (user["accessKey"] as? String) ?? ""
self.name = (user["name"] as? String) ?? ""
Note that (user["id"] as? String)?.toInt() ?? 0 uses multiple features of the Swift language to prevent a crash:
- If
"id" is not a valid key in the user dictionary, user["key"] will return nil. Casting nil to String with as? will return nil. The optional chain ? will just return nil instead of calling toInt() and finally the nil coalescing operator ?? will turn that into 0.
- If
user["id"] is in fact another type, then as? String will return nil and that will become 0 as above.
- If
user["id"] is a String that doesn't convert to an Int, like "two", then toInt() will return nil which ?? will convert to 0.
- Finally, if
user["id"] is a String that converts to an Int, then toInt() will return an Int? (optional Int) that ?? will unwrap
For Swift 2.0:
self.id = Int(user["id"] as? String ?? "") ?? 0
self.accStatus = Int(user["accStatus"] as? String ?? "") ?? 0
Like above Int(user["id"] as? String ?? "") ?? 0 uses multiple features of the Swift language to prevent a crash:
- If
"id" is not a valid key in the user dictionary, user["key"] will return nil. Casting nil to String with as? will return nil. The nil coalescing operator ?? will turn that into "". Int("") will return nil which the second ?? will coalesce into 0.
- If
user["id"] is another type, then as? String will return nil and that will become 0 as above.
- If
user["id"] is a String that doesn't convert to an Int, then Int() will return nil which ?? will convert to 0.
- Finally, if
user["id"] is a String that converts to an Int, then Int() will return an Int? (optional Int) that ?? will unwrap.