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

我刚刚从 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
}

在更新之前,我可以简单地将 NSData 发送到我的服务器,但是现在我很难解析令牌。

我错过了什么?

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

    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
}
36135 次浏览

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.

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

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

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: "<>"))
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print(token)
}

try this

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

Swift 3

The best and easiest way.

deviceToken.base64EncodedString()

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: "")

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()
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {


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




}

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