Swift 3 - device tokens are now being parsed as '32BYTES'

IosSwiftSwift3

Ios Problem Overview


I just updated from Xcode 7 to the 8 GM and amidst the Swift 3 compatibility issues I noticed that my device tokens have stopped working. They now only read '32BYTES'.

	func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
	print(deviceToken) // Prints '32BYTES'
	print(String(data: deviceToken , encoding: .utf8)) // Prints nil
}

Before the update I was able to simply send the NSData to my server, but now I'm having a hard time actually parsing the token.

What am I missing here?

Edit: I just testing converting back to NSData and I'm seeing the expected results. So now I'm just confused about the new Data type.

	func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
	print(deviceToken) // Prints '32BYTES'
	print(String(data: deviceToken , encoding: .utf8)) // Prints nil
	
	let d = NSData(data: deviceToken)
	print(d) // Prints my device token
}

Ios Solutions


Solution 1 - Ios

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print(token)
}

Solution 2 - Ios

I had the same problem. This is my solution:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    var token = ""
    for i in 0..<deviceToken.count {
        token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }
    print(token)
}

Solution 3 - Ios

Here is my Swift 3 extension to get a base-16 encoded hex string:

extension Data {
    var hexString: String {
        return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
    }
}

Solution 4 - Ios

The device token has never been a string and certainly not a UTF-8 encoded string. It's data. It's 32 bytes of opaque data.

The only valid way to convert the opaque data into a string is to encode it - commonly through a base64 encoding.

In Swift 3/iOS 10, simply use the Data base64EncodedString(options:) method.

Solution 5 - Ios

Try this:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

   let token = String(data: deviceToken.base64EncodedData(), encoding: .utf8)?.trimmingCharacters(in: CharacterSet.whitespaces).trimmingCharacters(in: CharacterSet(charactersIn: "<>")) 
}

Solution 6 - Ios

try this

if #available(iOS 10.0, *) {
   let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
}

Solution 7 - Ios

> Swift 3

The best and easiest way.

deviceToken.base64EncodedString()

Solution 8 - Ios

This one wasn't stated as an official answer (saw it in a comment), but is what I ultimately did to get my token back in order.

let tokenData = deviceToken as NSData
let token = tokenData.description
    
// remove any characters once you have token string if needed
token = token.replacingOccurrences(of: " ", with: "")
token = token.replacingOccurrences(of: "<", with: ""
token = token.replacingOccurrences(of: ">", with: "")

Solution 9 - Ios

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let token = deviceToken.map({ String(format: "%02.2hhx", $0)}).joined()
     print("TOKEN: " + token)
    

}

Solution 10 - Ios

I just did this,

let token = String(format:"%@",deviceToken as CVarArg).components(separatedBy: CharacterSet.alphanumerics.inverted).joined(separator: "")

it gave the result same as,

let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()

Solution 11 - Ios

Get device token with proper format.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
{
            var formattedToken = ""
            for i in 0..<deviceToken.count {
                formattedToken = formattedToken + String(format: "%02.2hhx", arguments: [deviceToken[i]])
            }
            print(formattedToken)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1537360View Question on Stackoverflow
Solution 1 - IosRok GregoričView Answer on Stackoverflow
Solution 2 - IosOlegView Answer on Stackoverflow
Solution 3 - IosphatmannView Answer on Stackoverflow
Solution 4 - IosrmaddyView Answer on Stackoverflow
Solution 5 - IosuserView Answer on Stackoverflow
Solution 6 - IosbluenowhereView Answer on Stackoverflow
Solution 7 - IosMaselkoView Answer on Stackoverflow
Solution 8 - IosBill BurgessView Answer on Stackoverflow
Solution 9 - Iosfrancisco.garciaView Answer on Stackoverflow
Solution 10 - IosSatheeshView Answer on Stackoverflow
Solution 11 - IosBasir AlamView Answer on Stackoverflow