Reputation: 5330
An API I am consuming sometimes returns:
...
total: "40"
...
and sometimes:
...
total: 40
...
Is there a clean way to write a guard/let statement that will extract an int value regardless of whether the parsed json object is an NSString or an NSNumber?
NOTE: I'm looking for the answer how to decode the value, not a reference to a library that allows me to punt on solving it. I already know about SwiftyJSON etc.
Upvotes: 1
Views: 1190
Reputation: 285260
A different approach
let jsonDict : [String : CustomStringConvertible] = ["foo" : 40, "bar" : "50" ]
for (_, value) in jsonDict {
print(Int("\(value)")!)
}
Upvotes: 0
Reputation: 540065
You could use the fact that you can call any method on AnyObject
via optional chaining. Example:
let jsonDict : [String : AnyObject] = ["foo" : 40, "bar" : "50" ]
if let val = jsonDict["foo"]?.integerValue
{
print(val) // 40
}
if let val = jsonDict["bar"]?.integerValue
{
print(val) // 50
}
If the value for the key does not exist, or does not respond
to integerValue
, the result is nil
and the optional binding
fails. Otherwise, the integer value is assigned to val
.
Upvotes: 1
Reputation: 5330
I realized that I could define a protocol specifying the integerValue
getter and empty protocol extensions to NSString
and NSNumber
, and then cast the value to that protocol:
protocol HasNumber {
var integerValue: Int { get }
}
extension NSString:HasNumber{}
extension NSNumber:HasNumber{}
and then:
guard let total = (json["total"] as? HasNumber)?.integerValue else { }
Upvotes: 0