Sid Mhatre
Sid Mhatre

Reputation: 3417

NSJSONSerialization Error : Why am I not able to catch the error in try catch block? swift 3.0

I am calling REST API to get a response from the server and also testing for bad data type to caught in try catch block nut app still crashes with below error:

Could not cast value of type '__NSArrayM' (0x10575ee00) to 'NSDictionary' (0x10575f2d8).

    let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print(error!)
            return
        }

        do {

           let responseObject = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! Dictionary<String,String>

            print(responseObject)

        } catch let jsonError {

            print(jsonError)
        }
    }
    dataTask.resume()

For this, I also found the solution that I should check data with JSON format first then use JSONSerialization.

if JSONSerialization.isValidJSONObject(data){
    responseObject = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! Dictionary<String,String>

}
else {

    print("Error")

} 

I want to know that if type cast value error not caught by the try-catch block then what is a use of try-catch block in network call. I can simply check for the JSON format and the pass the response object.

What is a good programming practice?

NOTE : Error is not an issue I just don't want my should crash an app when data type changes form dictionary to array or other than specified type.

Upvotes: 1

Views: 461

Answers (1)

Nirav D
Nirav D

Reputation: 72420

This is not about valid JSON, you are getting this crash because your JSON at root is Array not Dictionary and you are trying to cast the result of jsonObject(with:) to Dictionary that is the reason you are getting this crash also there is no need to specify mutableContainers with Swift.

do {

    let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as! [[String:Any]]
    print(responseObject)

} catch let jsonError {

    print(jsonError)
}

Edit: If you don't know your JSON time then you can use if let like this way.

do {

    let responseObject = try JSONSerialization.jsonObject(with: data, options: [])
    if let responseArray = responseObject as? [[String:Any]] {
        //Access array
    }
    else if let responseDictionary = responseObject as? [String:Any] {
        //Access dictionary
    }
    print(responseObject)

} catch let jsonError {

    print(jsonError)
}

Upvotes: 2

Related Questions