Search code examples
swiftios8nsdatansurl

Can't urlencode deviceToken (Swift)


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()  
}

Solution

  • 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() 
    
    }