user979331
user979331

Reputation: 11871

swift do try catch not working

I am trying to do a do, try, catch like so:

do {
   setQA = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! [AnyObject]
   print(setQA)
}
catch _ {
    setQA = nil
    self.customAlert("Error")
}

and I am trying to call a method to use UIAlertController, but it never reaches it.

This does not even get by the try, my app crashes with this error:

Could not cast value of type '__NSCFDictionary' (0x1a1773968) to 'NSArray'

THis is an expected error that will sometimes occur pending on user data, I just dont my app to crash and just display the alert

Upvotes: 1

Views: 1375

Answers (2)

RomOne
RomOne

Reputation: 2105

Actually this is coming from this part of your code :

JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! [AnyObject]

What you can do is something like that :

  1. First check if you have actually receive some data from your sever :
  2. Check the format of these data. Your code is crashing because it is trying to parse your JSON into a wrong format (here an array of object), so try to cover all possible cases.

result code would be something like this :

    if let realData = data as? Data{

             do {
                    if let setQA = try NSJSONSerialization.JSONObjectWithData( realData, options: NSJSONReadingOptions.AllowFragments) as? [AnyObject] {
                        //Check if the result is an Array
                    print(setQA)
                    }else if setQA = try NSJSONSerialization.JSONObjectWithData( realData, options: NSJSONReadingOptions.AllowFragments) as? [String : AnyObject] {
                        //Check if the result is a dictionnary
                    }
                }
                catch _ {
                    setQA = nil
                    self.customAlert("Error")
                }

            }else{
                //Check if you have at least some data
                self.customAlert("No data from server :(")
            }
}

In general, try to avoid the use of ! ;)

Upvotes: 3

Paulw11
Paulw11

Reputation: 114875

do/try/catch will catch errors that are thrown by some other method, but it won't catch runtime exceptions, such as you are getting from the forced downcast. For example, if data was invalid JSON then an error will be thrown and caught. In your case it seems the JSON is valid, but it is a dictionary, not an array.

You want something like

setQA = nil
do {
    if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? [AnyObject] {
        setQA = json
        print(setQA)
    } else {
        self.customAlert("Invalid response from server")
    }
} catch _ {
    self.customAlert("Error parsing JSON")
}

Upvotes: 2

Related Questions