Swift 3 - 设备令牌现在被解析为'32BYTES'

use*_*360 93 ios swift swift3

我刚刚从Xcode 7更新到8 GM并且在Swift 3兼容性问题中我注意到我的设备令牌已停止工作.他们现在只读'32BYTES'.

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

在更新之前,我能够简单地将NSData发送到我的服务器,但现在我很难解析令牌.

我在这里错过了什么?

编辑:我只是测试转换回NSData,我看到了预期的结果.所以现在我只是对新数据类型感到困惑.

    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
}
Run Code Online (Sandbox Code Playgroud)

Rok*_*rič 189

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

  • `%02x`也没关系. (4认同)

小智 35

我有同样的问题.这是我的解决方案:

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)
}
Run Code Online (Sandbox Code Playgroud)


pha*_*ann 29

这是我的Swift 3扩展,用于获取base-16编码的十六进制字符串:

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


rma*_*ddy 27

设备令牌从来就不是字符串,当然也不是UTF-8编码的字符串.这是数据.它是32字节的不透明数据.

将不透明数据转换为字符串的唯一有效方法是对其进行编码 - 通常通过base64编码.

在Swift 3/iOS 10中,只需使用该Data base64EncodedString(options:)方法即可.

  • 我支持我说的话.`NSData`或`Data`,没关系.数据的字节不是,也从来不是字符串.文档明确指出它是一组不透明的数据.您的代码曾经运作的事实就是运气.处理它总是不正确的方法.只需通过base64编码数据将数据转换为字符串.这是现在和以前的正确解决方案. (3认同)

小智 15

试试这个:

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

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

  • 现在它似乎返回不同的令牌 (2认同)

blu*_*ere 8

试试这个

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


Mas*_*lko 7

迅捷3

最好和最简单的方法。

deviceToken.base64EncodedString()
Run Code Online (Sandbox Code Playgroud)

  • 这是最简单的方法,但是如果要分发令牌,请小心服务器使用的服务器。许多API期望使用十六进制编码或Base-16。例如,Django推送通知。 (3认同)