如何将我的设备令牌 (NSData) 转换为 NSString?
我正在实施推送通知。我想将我的 APNS 令牌保存为字符串。
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
NSLog(@"%@", tokenString);
NSLog(@"%@", newDeviceToken);
}
第一行代码打印 null。第二个打印令牌。如何获取 NSString 形式的 newDeviceToken?
I am implementing push notifications. I'd like to save my APNS Token as a String.
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
NSLog(@"%@", tokenString);
NSLog(@"%@", newDeviceToken);
}
The first line of code prints null. the second prints the token. How can I get my newDeviceToken as an NSString?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
如果有人正在寻找在 Swift 中执行此操作的方法:
Swift 3 引入了具有值语义的
Data
类型。要将deviceToken
转换为字符串,您可以执行以下操作:使用
NSData
的旧答案:If anyone is looking for a way to do this in Swift:
Swift 3 introduces the
Data
type, with value semantics. To convert thedeviceToken
to a String, you can do as follows:Old answer using
NSData
:有人帮助了我,我只是路过
Someone Helped me with this.I am just passing along
你可以用这个
You could use this
对于那些想要 Swift 3 和最简单方法的人
For those who want in Swift 3 and most easier method
注意 - 当使用 iOS 13 或更高版本的 SDK 进行编译时,这将不起作用
使用以下命令:
Note - This will not work when compiling with the iOS 13 or later SDK
use this :
高票答案中
%02.2hhx
的解释:%
:引入x
转换说明符。02
:转换后的值的最小宽度为2。如果转换后的值的字节数少于字段宽度,则需要在左侧填充0
。.2
:给出x
转换说明符中显示的最小位数。hh
:指定x
转换说明符应用于有符号字符或无符号字符参数(该参数将根据整数提升进行提升,但其值应转换)在打印之前转换为有符号字符或无符号字符)。x
:无符号参数应转换为无符号十六进制格式,格式为“dddd”;使用字母“abcdef”。精度指定出现的最小位数;如果要转换的值可以用更少的位数表示,则应使用前导零进行扩展。默认精度为 1。使用显式精度为零转换零的结果不应为任何字符。有关更多详细信息,请参阅 IEEE printf 规范。
根据上面的解释,我认为将
%02.2hhx
更改为%02x
或%.2x
更好。对于Swift 5,以下方法都是可行的:
测试如下:
Explanation of
%02.2hhx
in the high vote answer:%
: Introduces thex
conversion specifier.02
: The minimum width of the converted value is 2. If the converted value has fewer bytes than the field width, it shall be padded with0
on the left..2
: Gives the minimum number of digits to appear for thex
conversion specifier.hh
: Specifies that thex
conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing).x
: The unsigned argument shall be converted to unsigned hexadecimal format in the style "dddd"; the letters "abcdef" are used. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it shall be expanded with leading zeros. The default precision is 1. The result of converting zero with an explicit precision of zero shall be no characters.For more details, see the IEEE printf specification.
Based on the above explanation, I think it is better to change
%02.2hhx
to%02x
or%.2x
.For Swift 5, the following methods are all feasible:
The test is as follows:
在 iOS 13 中,描述将采用不同的格式。请使用下面的代码来获取设备令牌。
In iOS 13 the description will be in different format. Kindly use below code to fetch the device token.
这是我的解决方案,它在我的应用程序中运行良好:
stringWithFormat
将NSData
转换为NSString
It's my solution and It works well in my app:
NSData
toNSString
withstringWithFormat
我认为将 deviceToken 转换为十六进制字节字符串没有意义。为什么?您将其发送到后端,在后端将其转换回字节以推送到 APNS。因此,使用NSData的方法
base64EncodedStringWithOptions
,将其推送到服务器,然后使用反向base64解码数据:)这更容易:)I think converting deviceToken to hex byte string has no sense. Why? You will send it to your backend, where it will be transformed back to bytes to be pushed to APNS. So, use NSData's method
base64EncodedStringWithOptions
, push it to server, and then use reverse base64decoded data :) That is so much easier :)在 iOS 13 中
description
将中断,因此请使用它。为了清楚起见,让我们将其分解并解释每个部分:
map 方法对序列的每个元素进行操作。由于 Data 是 Swift 中的字节序列,因此会针对 deviceToken 中的每个字节评估传递的闭包。
String(format:) 初始化程序使用 %02x 格式说明符评估数据中的每个字节(由匿名参数 $0 表示),以生成字节/8 位整数的零填充、2 位十六进制表示形式。
收集由 map 方法创建的每个字节表示后,joined() 将每个元素连接成单个字符串。
PS 不要使用描述在 iOS 12 和 iOS 13 中给出不同的字符串,并且根据未来的范围不安全。 开发人员不应依赖特定格式来描述对象。
有关详细信息,请阅读
In iOS 13
description
will break so use thisFor clarity, let’s break this down and explain each part:
The map method operates on each element of a sequence. Because Data is a sequence of bytes in Swift, the passed closure is evaluated for each byte in deviceToken.
The String(format:) initializer evaluates each byte in the data (represented by the anonymous parameter $0) using the %02x format specifier, to produce a zero-padded, 2-digit hexadecimal representation of the byte / 8-bit integer.
After collecting each byte representation created by the map method, joined() concatenates each element into a single string.
P.S don't use description gives different string in iOS 12 and iOS 13 and not safe as per future scope. Developers shouldn’t have relied on a specific format for an object’s description.
For more information read This.
2020
令牌作为文本...
或者如果您愿意
(结果相同)
2020
token as text...
or if you prefer
(result is the same)
这是一个稍微短一点的解决方案:
This is a little bit shorter solution:
函数式 Swift 版本
一个衬垫:
这里采用可重用且自记录的扩展形式:
或者,使用
reduce("",combine: +)
而不是joinWithSeparator("")
来被同事视为职能大师。编辑:我将 String($0, radix: 16) 更改为 String(format: "%02x", $0),因为一位数字需要填充零
(我还不知道如何将问题标记为重复)的 另一个,所以我刚刚再次发布我的答案)
Functional Swift version
One liner:
Here's in a reusable and self documenting extension form:
Alternatively, use
reduce("", combine: +)
instead ofjoinWithSeparator("")
to be seen as a functional master by your peers.Edit: I changed String($0, radix: 16) to String(format: "%02x", $0), because one digit numbers needed to having a padding zero
(I don't know yet how to mark a question as a duplicate of this other one, so I just posted my answer again)
把我的答案扔到一堆。避免使用字符串解析;文档不保证 NSData.description 始终以这种方式工作。
Swift 3 实现:
Throwing my answer on the pile. Avoid using string parsing; It's not guaranteed by the docs that NSData.description will always work that way.
Swift 3 Implementation:
这对你有用,
This will work for you,
我尝试使用格式
"%02.2hhx"
和"%02x"
测试两种不同的方法,结果是最快的是
"%02x"
平均为 2.0 vs 简化版本的 2.6:I've tried to test two different methods with format
"%02.2hhx"
and"%02x"
and the result is that the fastest is
"%02x"
at average 2.0 vs 2.6 for the reduced version:以下是在 Xamarin.iOS 中执行此操作的方法
Here's how you do it in Xamarin.iOS
使用 updateAccumulatedResult 比此处找到的各种其他方法更有效,因此这是对
Data
字节进行字符串化的最快捷方法:Using updateAccumulatingResult is more efficient than the various other approaches found here, so here's the Swiftiest way to stringify your
Data
bytes:2023
或:
要详细了解为什么建议采用
02.2hhx
格式,您可以阅读 NSHipster 上的这篇文章 和 IEEE 规范。2023
or:
To learn more about why the format
02.2hhx
is suggested, you can read this post on NSHipster and the IEEE specification.对于斯威夫特:
For Swift :
迅速:
Swift:
一条线解决方案怎么样?
Objective C
Swift
What about one line solution?
Objective C
Swift
迅速
Swift
使用优秀的类别!
// .h 文件
// .m 文件
@end
// AppDelegate.m
工作正常!
Use excellent category!
// .h file
// .m file
@end
// AppDelegate.m
Works fine!
Swift 3:
如果有人正在寻找一种在 Swift 3 中获取设备令牌的方法。请使用以下修改后的代码片段。
Swift 3:
If any one is looking for a way to get device token in Swift 3. Use the below modified snippet.
@kulss 在这里发布的解决方案虽然缺乏优雅但具有简单性,但在 iOS 13 中不再适用,因为
description
对于 NSData 的工作方式有所不同。不过,您仍然可以使用 debugDescription 。The solution @kulss posted here, while lacking in elegance but having the virtue of simplicity no longer works in iOS 13, since
description
will work differently for NSData. You can still usedebugDescription
though.尝试这个,除非数据以空终止。
NSString* newStr = [[NSString alloc] initWithData:newDeviceToken
编码:NSUTF8StringEncoding];
Try this one unless the data is null-terminated.
NSString* newStr = [[NSString alloc] initWithData:newDeviceToken
encoding:NSUTF8StringEncoding];