0

I try to adapt my Android application on iPhone, but when I ask my server to get a JSON object I have a fatal error:

fatal error: unexpectedly found nil while unwrapping an Optional value

I think I have a bad initialization of my text field in my story board or something else but I can't find my error.

The print(jsonResult) gives me the good JSON but after I have my fatal error that appear.

import UIKit

class ViewController: UIViewController {



@IBOutlet weak var labelCategory: UILabel!
@IBOutlet weak var imageViewOneTrash: UIImageView!
@IBOutlet weak var textFieldCoordinate: UITextField!
@IBOutlet weak var textFieldAddress: UITextField!
@IBOutlet weak var buttonShare: UIButton!
@IBOutlet weak var buttonCoppy: UIButton!
@IBOutlet weak var buttonDelete: UIButton!
@IBOutlet weak var buttonMaps: UIButton!
@IBOutlet weak var addressTxtFld: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // 1
    let urlAsString = "http://www.website.sample"
    let url = NSURL(string: urlAsString)!
    let urlSession = NSURLSession.sharedSession()

    //2
    let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
        if (error != nil) {
            print(error!.localizedDescription)
        }

        // 3
        do{
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? [String:AnyObject] {

                print(jsonResult)
                // 4
                let jsonAddress: String! = jsonResult["trash_temp_address"] as! String

                dispatch_async(dispatch_get_main_queue(), {
                    self.addressTxtFld.text = jsonAddress
                })
            }

        }catch let error as NSError {
            print(error.localizedDescription)
        }

    })
    // 5
    jsonQuery.resume()

}

  override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

The result of the print(jsonResult) is:

["result": <__NSArrayM 0x15d62770>(
{
    "cat_name" = Mobilier;
    "country_name" = France;
    "town_name" = Toulon;
    "town_postal_code" = 83200;
    "trash_temp_address" = "278-338 Chemin du Jonquet";
    "trash_temp_date_time" = "2016-05-22 17:49:14";
    "trash_temp_fk_category" = 2;
    "trash_temp_id" = 99;
    "trash_temp_img" = "/pics/IMG_20160622_174846.jpg.png";
    "trash_temp_latitude" = "43.1395197";
    "trash_temp_longitude" = "5.9106404";
}
)
]
2
  • where do you get this error, which line? Commented Jun 22, 2016 at 19:52
  • I don"t have a line number, I put the json in my question Commented Jun 22, 2016 at 19:59

3 Answers 3

3
  • The root object is a dictionary with one key result.
  • The value for key result is an array of dictionaries

This gets the value for key trash_temp_address

if let jsonRootObject = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject] { // mutable containers are not needed

    print(jsonRootObject)
    if let jsonResult = jsonRootObject["result"] as? [[String:String]],
       jsonAddress = jsonResult[0]["trash_temp_address"] {    
          dispatch_async(dispatch_get_main_queue()) {
             self.addressTxtFld.text = jsonAddress
          }
    }
    ...
Sign up to request clarification or add additional context in comments.

Comments

0

Your print(jsonResult)

shows an object with a result key and an array with one object that has your "trash_temp_address"

You access that something like this:

let result = jsonResult["result"] as! [AnyObject]
let resultObj = result[0] as! [String: AnyObject]
let jsonAddress = resultObj["trash_temp_address"] as! String

(you might need to correct this, as I am not trying it in Xcode)

Comments

0

First possible crash could happen here:

let jsonAddress: String! = jsonResult["trash_temp_address"] as! String

Try to avoid implicit unwrapping of optionals. Moreover text property is already optional. So and we can write:

let jsonAddress = jsonResult["trash_temp_address"] as? String

Next crash could happen here:

self.addressTxtFld.text = jsonAddress

if addressTxtFld outlet is not connected in storyboard or nib file. To fix it write this

self.addressTxtFld?.text = jsonAddress

P.S. These advices fixes possible crashes. But not wrong logic. With new information (JSON structure) it is obvious logic is wrong. @vadian gave you an example of correct parsing logic.

2 Comments

the "let jsonAddress = jsonResult["trash_temp_address"] as? String" delete the fatal error, but when I do print(jsonAddress) it print nil
yes. Because jsonResult is wrapping dictionary. I updated my answer and suggesting to look at @vadian answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.