Search code examples
jsonswiftintunsigned-integer

Parsing unsigned integer from JSON dictionary in Swift


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?


Solution

  • 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)
    }