-5

I get the error "Fatal error: Unexpectedly found nil while unwrapping an optional value". I am trying to fetch JSON as a dictionary from my server. How do I throw the error if the data is nil?

    let jsonUrl = "jsonurl"
    let session = NSURLSession.sharedSession()
    let shotsUrl = NSURL(string: jsonUrl)
    let task = session.dataTaskWithURL(shotsUrl!, completionHandler: {
        (data,response,error) -> Void in
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) // Get error
            dispatch_async(dispatch_get_main_queue()) {
                for newData in json as! [Dictionary<String, AnyObject>] {
                   // do stuff
                }
            }
        } catch {

        }
    })
    task.resume()

Edit: to clarify, I am testing when there is no internet connection, it should ignore the error thrown, instead it gives an error. I tried

guard let data = data else { return }
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)

but it says "Cannot force unwrap of optional type 'NSData'" on the let json line

  • place this above your let json: **guard let data = data else { return }**, that'll safely unwrap your optional. But that's not your problem, your data is coming back nil. – Dan Beaulieu Jan 14 '16 at 15:16
  • possible duplicate : http://stackoverflow.com/questions/28863262/unexpectedly-found-nil-while-unwrapping-an-optional-value-reading-json – Dan Beaulieu Jan 14 '16 at 15:18
  • Use safe unwrapping for your data. http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark-mean-in-the-swift-language Do not force unwrap with `!`. – Eric Aya Jan 14 '16 at 15:24

2 Answers2

1

Instead of guard the data parameter handle the error returned in the completion handler. If there is no error then data can be safely unwrapped.

let task = session.dataTaskWithURL(shotsUrl!, completionHandler: {
    (data,response,error) -> Void in
    if error != nil {
      // do proper error handling

    } else {
        do {
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
        ...

And add also appropriate error handling in the catch scope. It seems to be annoying but can be very useful. ;-)

vadian
  • 274,689
  • 30
  • 353
  • 361
0

You are force unwrapping data by saying data!. This means if it expects data not to be nil, which it will always be if there is no internet connection. You at least need to check data is nil before you force unwrap, and then handle how you want your object created if it is nil.

if data != nil {
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) // Get error
            dispatch_async(dispatch_get_main_queue()) {
                for newData in json as! [Dictionary<String, AnyObject>] {
                   // do stuff
                }
            }
        } catch {

        }
} else {
    //handle object creation if data is nil
}
NSGangster
  • 2,397
  • 12
  • 22
  • This is a minimal solution to solve your force unwrapping problem, Your code is far from best practice when handling error's from dataTask completion. You should be checking your errors too in a similar matter and handle them if an error exits with `if error != nil` and checking the response you get back. – NSGangster Jan 14 '16 at 15:55