iosjsonruby-on-railsswift

Swift iOS NSJsonSerialization fails silently


I have the following code fetching JSON data via an API:

    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
    // print("Response: \(response)")
    // print("DATA: \(data)")
    
    if data != nil {
        do {

            
            print( NSString(data: data!, encoding: NSUTF8StringEncoding))
            
            if let jsonResults =  try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray {
                print("\n\nThe return JSON looks like this: \(jsonResults)\n\n")
            }
        } catch {
            print("\n\nProblem getting JSON back from GET API.\n\n")
        }
        
    }  else  {
       print("API Not Available")  // data was nil
    }

}) // task

task.resume()

The "print" of the NSString shows what to my eyes looks like valid JSON. The console shows this as:

Optional({"id":15,"user_id":11,"breed_id":593,"gender":"Male","age_years":5,"tally":{"count":1246,"struvite":716,"calcium_oxalate":388,"urate":217,"calcium_phosphate":30,"silica":21,"compound":41},"created_at":"2016-02-04T08:26:14.719-06:00","updated_at":"2016-02-04T08:26:14.719-06:00"})

However, the if let jsonResults = statement does execute successfully (there is no jsonResults printed) and the catch does not execute either -- so it seems like a silent error.

A very similar call works on another part of the API. The only big difference is that "tally" in the JSON return on this call is nested.

Any suggestions are appreciated.


Solution

  • The answer was a combination of dzk and ishaq's responses.

    I replaced

    if let jsonResults =  try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
    

    with:

    if let jsonResults =  try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
    

    The essential piece was casting it as a Dictionary, not an Array.