-1

I have been working on my first iOS Swift project, and I am running into difficulty with a fatal error. This error reports unexpectedly found nil while unwrapping optional value only when getting an error message from the API being called.

Here is the Swift code

@IBAction func pressScan(sender: AnyObject) {

        let barcode = lastCapturedCode

    print("Received following barcode: \(barcode)")

    let url = "https://api.nutritionix.com/v1_1/item?upc="

    let urlWithUPC = url + barcode! + "&appId=[app ID goes here]&appKey=[app key goes here]"

    print("API Query: "+urlWithUPC)

    NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlWithUPC)!) { data, response, error in
        // Handle result
        print("Checked the bar code")


        //  let JSONData = NSData()
        do {
           let JSON = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions(rawValue: 0))


            guard let JSONDictionary :NSDictionary = JSON as? NSDictionary else {
                print("Not a Dictionary")
                // put in function
                return
            }
            print("JSONDictionary \(JSONDictionary)")


            let foodScreenName = (JSONDictionary as NSDictionary)["item_name"] as! String

            let foodBrandName = (JSONDictionary as NSDictionary)["brand_name"] as! String


            let fullFoodName = foodBrandName + " " + foodScreenName

            dispatch_async(dispatch_get_main_queue(),{

                self.foodName.text = fullFoodName
            });



        }
        catch let JSONError as NSError {
            print("\(JSONError)")
        }



        }.resume


}

Here is the JSON result returned with an error

JSONDictionary {
"error_code" = "item_not_found";
"error_message" = "Item ID or UPC was invalid";
"status_code" = 404;
}

Here is the JSON result if the item is found by the API

    JSONDictionary {
   "item_id": "51c3d78797c3e6d8d3b546cf",

   "item_name": "Cola, Cherry",

   "brand_id": "51db3801176fe9790a89ae0b",

   "brand_name": "Coke",
   "item_description": "Cherry",
   "updated_at": "2013-07-09T00:00:46.000Z",
   "nf_ingredient_statement": "Carbonated Water, High Fructose Corn Syrup and/or Sucrose, Caramel Color, Phosphoric Acid, Natural Flavors, Caffeine.",
   "nf_calories": 100,
   "nf_calories_from_fat": 0,
   "nf_total_fat": 0,
   "nf_saturated_fat": null,
   "nf_cholesterol": null,
   "nf_sodium": 25,
   "nf_total_carbohydrate": 28,
   "nf_dietary_fiber": null,
   "nf_sugars": 28,
   "nf_protein": 0,
   "nf_vitamin_a_dv": 0,
   "nf_vitamin_c_dv": 0,
   "nf_calcium_dv": 0,
   "nf_iron_dv": 0,
   "nf_servings_per_container": 6,
   "nf_serving_size_qty": 8,
   "nf_serving_size_unit": "fl oz",
}
CM.
  • 519
  • 5
  • 19
  • "unexpectedly found nil" On what line of your code? – matt Oct 10 '15 at 16:46
  • Fix it? Never ever use `!` again (except for `!=`). Wrap all those cases in if-lets or similar constructs. – HAS Oct 10 '15 at 16:48
  • Your error response also contains JSON, so you should check that response statusCode == 200 before attempting to parse the JSON as a found item. Also a good idea to use ? instead of ! when parsing fields in case the server didn't send them. – Mike Taverne Oct 10 '15 at 16:54
  • You get this assertion because in the case of error there is no key for `(JSONDictionary as NSDictionary)["item_name"] as! String` or `(JSONDictionary as NSDictionary)["brand_name"] as! String`. You first need to check if they exist. – HAS Oct 10 '15 at 16:55
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – jtbandes Oct 10 '15 at 19:00

1 Answers1

1

Since your dictionary structure changes and you are not sure on few keys being present, you must do a safe check before using them like this:

if let screenName = (JSONDictionary as NSDictionary)["item_name"] {
    foodScreenName = screenName as! String
}

if let brandName = (JSONDictionary as NSDictionary)["brand_name"] {
    foodBrandName = brandName as! String
}
Abhinav
  • 37,684
  • 43
  • 191
  • 309