You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将iOS设备令牌字符串转换回Data格式?

将APNs设备令牌字符串转回原始Data格式

你之前把APNs设备令牌(Data类型)转成十六进制字符串的方式是对的,但用Data(tokenString.utf8)转回的方法完全错误——因为这是把字符串里每个字符的UTF-8编码转成了Data,和原始的设备令牌字节完全不匹配。

正确的做法是把十六进制字符串每两个字符一组,解析成对应的8位字节(UInt8),再拼接成Data。下面是实现代码:

扩展String实现转换

extension String {
    func toAPNsDeviceTokenData() -> Data? {
        // 先清理字符串:转小写并移除可能存在的空格(兼容某些格式的令牌字符串)
        let cleanedToken = self.lowercased().replacingOccurrences(of: " ", with: "")
        // 十六进制字符串长度必须是偶数,否则无法完整解析每个字节
        guard cleanedToken.count % 2 == 0 else { return nil }
        
        var tokenData = Data()
        var currentIndex = cleanedToken.startIndex
        
        while currentIndex < cleanedToken.endIndex {
            // 截取两个字符作为一组
            let nextIndex = cleanedToken.index(currentIndex, offsetBy: 2)
            let byteString = cleanedToken[currentIndex..<nextIndex]
            // 将十六进制字符串转成UInt8字节
            guard let byte = UInt8(byteString, radix: 16) else { return nil }
            tokenData.append(byte)
            currentIndex = nextIndex
        }
        
        return tokenData
    }
}

使用示例

let savedTokenString = "cd414ecaf22687b31b602cec11c7c4d797ead5cfece5fc59321e7ac35e36d4c1"

if let restoredTokenData = savedTokenString.toAPNsDeviceTokenData() {
    // 验证转换是否正确:转回字符串应该和原字符串一致
    let convertedBackToString = restoredTokenData.map { String(format: "%02.2hhx", $0) }.joined()
    print(convertedBackToString == savedTokenString.lowercased()) // 输出 true,说明转换正确
}

为什么你的原有方法不对?

你之前用Data(tokenString.utf8)得到的Data,其实是把字符串里每个字符的UTF-8编码存成了字节。比如原字符串里的"cd",会被转成0x63('c'的ASCII码)和0x64('d'的ASCII码)两个字节,所以转回十六进制字符串后就变成了"6364",这和原始设备令牌的字节完全无关,自然不符合SDK的要求。

内容的提问来源于stack exchange,提问作者oBo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:31:17