0

I would like to send the deviceToken using NSURL session to my server, but it crashes every time. I've tried to find a way to convert the DataObject (the deviceToken) into NSString but did not succeed so far.

Error: "fatal error: unexpectedly found nil while unwrapping an Optional value"

Any help s greatly appreciated. Here's my code

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken   deviceToken: NSData!) {
    let urlPath = "http://example.com/deviceToken=\(deviceToken)"
    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
        if(error != nil) {
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        }
        var err: NSError?

    })

    task.resume()  
}
Matt
  • 15
  • 1
  • 5
  • `"[http://example.com]&deviceToken=\(deviceToken)"` should be `"http://example.com&deviceToken=\(deviceToken)"`, without the square brackets. Where did you get that from? – Martin R Jan 10 '15 at 23:04
  • 1
    Actually it probably should be `"http://example.com?deviceToken=\(deviceToken)"`. – Martin R Jan 10 '15 at 23:18

1 Answers1

4

Can you pinpoint what variable is being unwrapped and returning nil? I can't see anything that would cause that, except the URL, so your error might be an invalid URL. Remember NSURL validates the string given according to a strict syntax (RFC 2396). Try this URL (without the deviceToken) and see if that makes any difference:

let urlPath = "http://example.com/?deviceToken"

On a sidenote, the device token needs to be URL encoded, please see this answer. Your whole method would then be as follows:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for var i = 0; i < deviceToken.length; i++ {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }
    let urlPath = "http://example.com/?deviceToken=\(tokenString)"
    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
        if(error != nil) {
            // If there is an error in the web request, print it to the console
            println(error.localizedDescription)
        }
        var err: NSError?

    })

    task.resume() 

}
Community
  • 1
  • 1
Emil
  • 7,220
  • 17
  • 76
  • 135
  • thanks a lot. I was trying to unwrap deviceToken, so your solution works fine. – Matt Jan 11 '15 at 00:00
  • 1
    Very minor comment - ```format: "%02hhx"``` is enough. No precision needed as every byte of ```device token``` is integer. See http://pubs.opengroup.org/onlinepubs/009695399/functions/printf.html – Sergey M Jun 08 '15 at 06:25
  • This is deprecated in Xcode 7.3, please update your answer – Lucas van Dongen Mar 22 '16 at 16:46