33

我以NSData对象的形式接收 iPhone 设备令牌。当我测试我的通知脚本功能时,我只从日志中复制了该对象并且通知运行良好。但是,当我现在尝试自动执行此操作时,我将设备令牌作为 ASCII 编码字符串以变量的形式发送

self.deviceToken = [[NSString alloc] initWithData:webDeviceToken encoding:NSASCIIStringEncoding];

我得到的字符串有一些时髦的字符,看起来类似于这个"å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

当服务器端脚本向该令牌发送通知时,我没有收到任何东西。

我需要解码一些东西吗?如何解码?

关注

4

6 回答 6

108

好的,我找到了解决方案。如果有人有同样的问题,忘记 ASCII 编码,只需使用以下行创建字符串:

NSString *deviceToken = [[webDeviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
于 2009-10-19T07:58:02.667 回答
43

如果有人正在寻找在 Swift 中执行此操作的方法:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }

    print("tokenString: \(tokenString)")
}

编辑:对于 Swift 3

Swift 3 引入了Data具有值语义的类型。要将其转换deviceToken为字符串,您可以执行以下操作:

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

    var token: String = ""
    for i in 0..<deviceToken.count {
        token += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
    }

    print(token)
}
于 2014-07-27T10:17:14.987 回答
5

我发现这个解决方案更好,因为 iOS 可以在将来的版本中更改描述的使用,因此将来对数据使用描述属性可能不可靠。我们可以通过从数据令牌字节创建十六进制令牌来直接使用它。

 - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
 const unsigned *tokenBytes = [deviceToken bytes];
 NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                  ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                  ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                  ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
 [[MyModel sharedModel] setApnsToken:hexToken];

}

我们还可以将设备令牌存储在我们的 NSUserdefaults 中,然后使用它来将其发送到我们的服务器。

于 2013-08-30T14:34:11.113 回答
2

我认为这不是一个好的解决方案,因为您必须在将通知发送到 Apple 服务器之前重建字符串。使用 Base64 编码来传输字符串或类似的东西。

于 2009-10-19T09:22:01.793 回答
0

将设备令牌转换为十六进制字符串的另一种方法

NSUInteger capacity = [deviceToken length] * 2;
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:capacity];
const unsigned char *dataBuffer = [deviceToken bytes];
NSInteger i;
for (i=0; i<[deviceToken length]; ++i) {
    [stringBuffer appendFormat:@"%02X", (NSUInteger)dataBuffer[i]];
}
NSLog(@"token string buffer is %@",stringBuffer);
于 2013-12-16T09:25:19.770 回答
0

对于斯威夫特 3:

var tokenString: String = ""
    for i in 0..<deviceToken.count {
        tokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
    }

    print(tokenString)

其他方法

创建数据扩展以获取十六进制字符串

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

并调用这个扩展

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.hexString()
    print("token: \(tokenString)")
}
于 2015-06-10T08:58:44.773 回答