Arun K
Arun K

Reputation: 840

Try block not working correctly

I'm working on a app in which the api is called through NSURLSession. When the Api works correctly there is no problem but when no data is received due to any error then after Serialization it throws error but the else block for it is never called

 let task = session.dataTaskWithRequest(request) { (let data, let response,  let error) in


        do {
            guard let data:NSData = data , let response: NSURLResponse = response where error == nil else {
                throw error!
            }

            guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else{
                print("Serialization failed") //This block never executes even if the Serialization Fails
                throw JSONError.ConversionFailed

            }

            guard json.valueForKey("success") != nil else {
                return
            }


            self.apidata = json
            dispatch_async(dispatch_get_main_queue()){
                self.tableView.reloadData()
            }
            print(json.valueForKey("success")!)

        }
        catch let error as JSONError{
            self.showalertview(error.rawValue)
            print(error.rawValue)
        } catch let error as NSError{


            print(error.debugDescription)
        }
    }

    task.resume()

What I'm doing wrong here???

Upvotes: 1

Views: 78

Answers (1)

Rob
Rob

Reputation: 437592

Consider:

do {
    guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else {
        // A
    }
} catch {
    // B
}

If NSJSONSerialization throws an error (i.e. if it wasn't really a JSON response or if the response was malformed), it will proceed directly to B and the guard statement doesn't come into play. The guard statement will only execute A if and only if (a) the NSJSONSerialization call, itself, didn't throw any errors (i.e. the JSON was well-formed); but (b) the cast to the the dictionary failed (e.g. the top level JSON object was an array instead of a dictionary). That's an extremely unlikely scenario (your server would have to accidentally return a well formed JSON response that was not a dictionary, e.g. a JSON array).


To accomplish what you want, you would use try? to make sure that NSJSONSerialization wouldn't throw any errors, itself:

do {
    guard let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else {
        // A
        throw JSONError.ConversionFailed 
    }
} catch {
    // B
}

By doing this, only if A performs a throw will B be called

Upvotes: 1

Related Questions