1

I am using the following function to upload a image to a given url. I built this function based on the answers given to these to questions: NSURLConnection Using iOS Swift and How to send UIImage in JSON format, by filling a NSDictionary

func uploadFileToUrl(url:NSURL){
    var request = NSMutableURLRequest(URL:url)
    request.HTTPMethod = "POST"
    request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(image))

    var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
    var error: AutoreleasingUnsafeMutablePointer<NSErrorPointer?> = nil

    var dataVal: NSData =  NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error:nil)!


    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

    if (error != nil) {
        println("Request didn't go through")
    }

    println("Synchronous\(jsonResult)")
}

However when I run my app I always get an "fatal error: unexpectedly found nil while unwrapping an Optional value" on the following line:

    var dataVal: NSData =  NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error:nil)!

What am I doing wrong? Thanks

Shruti Thombre
  • 989
  • 4
  • 11
  • 27
dschlossfr
  • 377
  • 5
  • 12

2 Answers2

2

First off, you aren't passing your error pointer when you make the request, so you will never know if that failed.

Secondly, as already mentioned, you are force unwrapping your dataVal variable without checking the value. So if your request did error and you don't handle it, you end up with the error you showed.

See the code below for a working example.

func uploadFileToUrl(url:NSURL){
    var request = NSMutableURLRequest(URL:url)
    request.HTTPMethod = "POST"
    request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(image))

    var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
    var HTTPError: NSError? = nil
    var JSONError: NSError? = nil

    var dataVal: NSData? =  NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: &HTTPError)

    if ((dataVal != nil) && (HTTPError == nil)) {
        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: &JSONError) as NSDictionary

        if (JSONError != nil) {
            println("Bad JSON")
        } else {
            println("Synchronous\(jsonResult)")
        }
    } else if (HTTPError != nil) {
        println("Request failed")
    } else {
        println("No Data returned")
    }
}
mtaylor
  • 1,130
  • 1
  • 8
  • 6
  • I'm putting var url = NSURL(string: "http://my/url") then exactly your code and getting a live build error: Value of optional type NSURL? not unwrapped; did you mean to use a ! or ?. If I add a !, then I get an error on the NSData.dataWithData line. If I make the suggested changes, I get fatal error: unexpectedly found nil while unwrapping an Optional value upon calling the function. Back to square one. Any ideas? – Andrew Mar 20 '15 at 00:17
1

If there's a problem, NSURLConnection.sendSynchronousRequest returns nil. You do have a problem, and it is returning nil. You are then force-unwrapping that nil with your exclamation mark. Hence the crash.

Instead, type dataVal as an NSData? which is what you are getting back (and remove the exclamation mark). Now you won't crash. Now in the next line look to see whether dataVal is nil. If it is, you know you've got a problem, and now you can read the error to see what the problem was.

If it isn't, now you can unwrap it and hand it off to NSJSONSerialization for interpretation.

matt
  • 515,959
  • 87
  • 875
  • 1,141