1

I'm trying to fetch data from my db but I have an exc_bad_instruction on my NSJSONSerialization.

func request(url:String, callback:(NSDictionary) -> ()){
        let nsURL = NSURL(string: url)

        let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!){
            (data, response, error) in
            //var error:NSError?
            var response:NSDictionary
            do{
                response = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
                callback(response)
            }catch{
                print("Something went wrong!")
            }


        }
        task.resume()
    }

Do you have any idea on why it's not working? Just to let you know something, I had to use the do, try, catch since Swift 2 because it was working great before!

Jeremy Dana
  • 107
  • 11
  • Are you sure the outermost object in your JSON is a dictionary? – Paulw11 Aug 03 '15 at 20:30
  • 1
    BTW, I'd encourage you to change that callback parameter to optional, and then ensure you call the callback even if you have an error (passing `nil` for the dictionary). It will be very frustrating to have an error (particularly runtime errors that are outside the app's control, such as network or server problems), but for the caller to not be informed of this situation. Note that Apple's completion handlers always have optional parameters (and also include `NSError` object so you know what the error was): I'd advise doing the same with your completion blocks. – Rob Aug 03 '15 at 20:53

1 Answers1

2

Without the full error message we're guessing regarding the precise problem, but you should guard against bad input data:

func request(url:String, callback:(NSDictionary) -> ()){
    let nsURL = NSURL(string: url)

    guard nsURL != nil else {
        print("URL not valid: \(url)")
        return
    }

    let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!){
        (data, response, error) in

        guard data != nil else {
            print("dataTaskWithURL failed: \(error)")
            return
        }

        do {
            if let response = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
                callback(response)
            } else {
                print("JSON parsing succeeded, but cast to dictionary failed")
            }
        } catch let parseError {
            print("Something went wrong: \(parseError)")
        }
    }
    task.resume()
}

The do-try-catch catches errors, not exceptions, so you have to test for valid URL and valid NSData yourself. Also, avoid forced unwrapping of optionals (e.g. !), especially when it is a plausible runtime error (e.g. no network). Use optional binding instead.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks for your answer, the code now runs but none of my data is displaying, according to the console, it looks like there is an issue with the connexion :/ I'll give it a look! Any thanks a lot for that! – Jeremy Dana Aug 03 '15 at 20:56