Parsing unsigned integer from JSON dictionary in Swift

2.7k views Asked by At

I'm trying to write code to parse a JSON value (which could be a String or an Integer in the JSON) to an optional unsigned integer (i.e. UInt?), being tolerant to the value being missing or not being parsable - I only want the result to have a value if the source data contains a legitimate positive value:

convenience init(jsonDictionary: NSDictionary) {
    ...
    var numLikesUnsigned: UInt?
    if let likesObj: AnyObject = jsonDictionary.valueForKey("likeCount") {
        let likes = "\(likesObj)"
        if let numLikesSigned = likes.toInt() {
            numLikesUnsigned = UInt(numLikesSigned)
        }
    }
    self.init(numLikesUnsigned)
}

This seems incredibly unwieldy. Is it really this hard?

1

There are 1 answers

0
rintaro On BEST ANSWER

you can simply do like this:

var numLikesUnsigned = (jsonDictionary["likeCount"]?.integerValue).map { UInt($0) }

Since NSString and NSNumber both has integerValue property, we can access .integerValue no matter which type is that.

let dict:NSDictionary = ["foo":42 , "bar":"42"]

let foo = dict["foo"]?.integerValue // -> 42 as Int?
let bar = dict["bar"]?.integerValue // -> 42 as Int?

And, Optional has .map method:

/// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.
func map<U>(f: (T) -> U) -> U?

You can:

let intVal:Int? = 42
let uintVal = intVal.map { UInt($0) } // 42 as UInt?

instead of:

let intVal:Int? = 42

let uintVal:UInt?
if let iVal = intVal {
    uintVal = UInt(iVal)
}