0

I am trying to write a method that scan the barcode then using http rest call to get some JSON data from a server. Alamofire doesn't work now and I tried many different ways.

Here is what I got now:

let getEndpoint: String = "45.55.63.218:8080/food?foodidentifier=\(code)"
    let requestURL: NSURL = NSURL(string: getEndpoint)!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) {
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        if (statusCode == 200) {
            print("Everyone is fine, file downloaded successfully.")
            do{
                //let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)

            }catch {
                print("Error with Json: \(error)")
            }

        }
    }
task.resume()

I get an error message: fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) on line: let httpResponse = response as! NSHTTPURLResponse

  • By the way, in addition to needing to add the scheme (e.g. `http://` or `https://`), assuming it's only `http://`, then you might also need to add your domain to the `NSAppTransportSecurity` as described in http://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http/31254874#31254874. – Rob Apr 07 '16 at 16:41

1 Answers1

0

The problem is that the forced cast to NSHTTPURLResponse will fail if response was nil (for example, if there was some error that prevented the request from being issued successfully, as in this case where the URL string was missing the http:// scheme prefix; but this could happen for any of a variety of issues, so one must anticipate and handle network errors gracefully). When processing responses from network requests, one should studiously avoid forced unwrapping/casting unless you have first confirmed that the value is valid and non-nil.

I would suggest:

  • using guard statements to safely check for nil values;
  • check that data was not nil and that error was nil before bothering to check status codes;

So, that might yield:

let task = session.dataTaskWithRequest(urlRequest) { data, response, error in
    guard data != nil && error == nil else {
        print(error)
        return
    }

    guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else {
        print("status code not 200; \(response)")
        return
    }

    print("Everyone is fine, file downloaded successfully.")
    do {
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
        print(json)
    } catch let parseError {
        print("Error with Json: \(parseError)")
    }
}
task.resume()
Rob
  • 415,655
  • 72
  • 787
  • 1,044