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.