iosswiftthemoviedb-api

EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0) crash


I am having the common problem of this error in my Swift code when attempting to access an API:

"NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)".

However, when I try using the common workarounds in the info.plist with NSAppTransportSecurity I get this:

"EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0)".

Below is my code, I cannot figure out what is going on here. Any assistance here would be much appreciated.

func getMoviesNowPlayingData(page:Int, completion: (dict: [String:Any]) -> ()) {
    
    let urlString : String = "https://api.themoviedb.org/3/movie/now_playing?api_key=ebea8cfca72fdff8d2624ad7bbf78e4c&page=\(page)"
    let escapedUrlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
    let apiURL = NSURL(string:escapedUrlString!)
    
    let session = NSURLSession.sharedSession()

    session.dataTaskWithURL(apiURL!, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in
        //NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) occurs here

        do {
            if let data2 = data {
                let jsonDict = try NSJSONSerialization.JSONObjectWithData(data2, options: NSJSONReadingOptions.MutableContainers) as! [String:Any]
                //EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0) crash occurs here
                completion(dict: jsonDict)
            }
        } catch {
            //handle NSError
            print("error")
        }
    }).resume()
}

Solution

  • The problem is the line that says:

    let jsonDict = try NSJSONSerialization.JSONObjectWithData(data2, options: NSJSONReadingOptions.MutableContainers) as! [String:Any]
    

    The forced cast, as! is failing. I'd discourage the use of forced casts, if you can. But, as to why it fails, JSON contains class types, so you should use AnyObject, not Any, e.g.:

    guard let jsonDict = try NSJSONSerialization.JSONObjectWithData(data2, options: []) as? [String: AnyObject] else {
        print("not a dictionary")
        return
    }
    
    // use `jsonDict` here
    

    In a comment above, you suggest that it failed when you tried casting it to a NSDictionary, too. I'd suggest you try that again, because if the JSON is a dictionary, the returned object is a NSDictionary, so that cast wouldn't fail. I suspect there was some other problem going on when you tried that.