如何将我的设备令牌(NSData)转换为NSString?
我正在实施推送通知。 我想将我的APNS令牌保存为一个string。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken { NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding]; NSLog(@"%@", tokenString); NSLog(@"%@", newDeviceToken); }
代码的第一行输出null。 第二个打印令牌。 我怎样才能得到我的newDeviceToken作为一个NSString?
用这个 :
NSString * deviceTokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""] stringByReplacingOccurrencesOfString: @" " withString: @""]; NSLog(@"The generated device token string is : %@",deviceTokenString);
如果有人正在寻找一种方法在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
types和值语义。 要将deviceToken
转换为string,可以执行如下操作:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() print(token) }
有人帮助我,我只是路过
- (void)application:(UIApplication *)application 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]; }
你可以用这个
- (NSString *)stringWithDeviceToken:(NSData *)deviceToken { const char *data = [deviceToken bytes]; NSMutableString *token = [NSMutableString string]; for (NSUInteger i = 0; i < [deviceToken length]; i++) { [token appendFormat:@"%02.2hhX", data[i]]; } return [token copy]; }
对于那些想要Swift 3和最简单的方法
func extractTokenFromData(deviceToken:Data) -> String { let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) return token.uppercased(); }
这是我的解决scheme,它适用于我的应用程序:
NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
- 使用
stringWithFormat
将NSData
转换为NSString
- 修剪“<>”
- 删除空格
这是一个短一点的解决scheme:
NSData *token = // ... const uint64_t *tokenBytes = token.bytes; NSString *hex = [NSString stringWithFormat:@"%016llx%016llx%016llx%016llx", ntohll(tokenBytes[0]), ntohll(tokenBytes[1]), ntohll(tokenBytes[2]), ntohll(tokenBytes[3])];
functionSwift版本
一个class轮:
let hexString = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes), count: data.length).map { String(format: "%02x", $0) }.joinWithSeparator("")
这里有一个可重复使用和自我logging的扩展forms:
extension NSData { func base16EncodedString(uppercase uppercase: Bool = false) -> String { let buffer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count: self.length) let hexFormat = uppercase ? "X" : "x" let formatString = "%02\(hexFormat)" let bytesAsHexStrings = buffer.map { String(format: formatString, $0) } return bytesAsHexStrings.joinWithSeparator("") } }
或者,使用reduce("", combine: +)
而不是joinWithSeparator("")
作为您的同行的function主。
编辑:我更改string($ 0,基数:16)为string(格式:“%02x”,$ 0),因为一个数字需要填充零
(我还不知道如何将问题标记为另一个问题的重复,所以我只是再次发布我的答案)
我认为将deviceToken转换为hex字节的string是没有意义的。 为什么? 你会把它发送到你的后端,在那里它将被转换回被推送到APNS的字节。 所以,使用NSData的方法base64EncodedStringWithOptions
,将其推送到服务器,然后使用反向base64解码的数据:)这是太容易了:)
NSString *tokenString = [tokenData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
一线解决scheme呢?
目标C
NSString *token = [[data.description componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet]invertedSet]]componentsJoinedByString:@""];
迅速
let token = data.description.componentsSeparatedByCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet).joinWithSeparator("")
对于Swift:
var characterSet: NSCharacterSet = NSCharacterSet( charactersInString: "<>" ) var deviceTokenString: String = ( deviceToken.description as NSString ) .stringByTrimmingCharactersInSet( characterSet ) .stringByReplacingOccurrencesOfString( " ", withString: "" ) as String println( deviceTokenString )
把我的答案扔在一堆。 避免使用stringparsing; 文档无法保证NSData.description将始终以这种方式工作。
Swift 3实现:
extension Data { func hexString() -> String { var bytesPointer: UnsafeBufferPointer<UInt8> = UnsafeBufferPointer(start: nil, count: 0) self.withUnsafeBytes { (bytes) in bytesPointer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(bytes), count:self.count) } let hexBytes = bytesPointer.map { return String(format: "%02hhx", $0) } return hexBytes.joined() } }
迅速:
let tokenString = deviceToken.description.stringByReplacingOccurrencesOfString("[ <>]", withString: "", options: .RegularExpressionSearch, range: nil)
迅速
// make sure that we have token for the devie on the App func application(application: UIApplication , didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { var tokenStr = deviceToken.description tokenStr = tokenStr.stringByReplacingOccurrencesOfString("<", withString: "", options: [], range: nil) tokenStr = tokenStr.stringByReplacingOccurrencesOfString(">", withString: "", options: [], range: nil) tokenStr = tokenStr.stringByReplacingOccurrencesOfString(" ", withString: "", options: [], range: nil) print("my token is: \(tokenStr)") }
我试图用格式"%02.2hhx"
和"%02x"
来testing两种不同的方法
var i :Int = 0 var j: Int = 0 let e: Int = Int(1e4) let time = NSDate.timeIntervalSinceReferenceDate while i < e { _ = deviceToken.map { String(format: "%02x", $0) }.joined() i += 1 } let time2 = NSDate.timeIntervalSinceReferenceDate let delta = time2-time print(delta) let time3 = NSDate.timeIntervalSinceReferenceDate while j < e { _ = deviceToken.reduce("", {$0 + String(format: "%02x", $1)}) j += 1 } let time4 = NSDate.timeIntervalSinceReferenceDate let delta2 = time4-time3 print(delta2)
结果是最快的是平均2.0的"%02x"
和缩小版本的2.6:
deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
-(NSString *)deviceTokenWithData:(NSData *)data { NSString *deviceToken = [[data description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""]; return deviceToken; }
NSString *tokenString = [[newDeviceToken description] stringByReplacingOccurrencesOfString:@"[<> ]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [[newDeviceToken description] length])];
Swift 3:
如果有人正在寻找一种方法来获取设备令牌在Swift 3中使用下面修改后的代码片段。
let characterSet: CharacterSet = CharacterSet( charactersIn: "<>" ) let deviceTokenString: String = (deviceToken.description as NSString) .trimmingCharacters(in: characterSet as CharacterSet) .replacingOccurrences(of: " ", with: "") .uppercased() print(deviceTokenString)
使用优秀的类别!
// .h文件
@interface NSData (DeviceToken) - (NSString *)stringDeviceToken; @end
// .m文件
#import "NSData+DeviceToken.h" @implementation NSData (DeviceToken) - (NSString *)stringDeviceToken { const unsigned *deviceTokenBytes = [deviceToken bytes]; NSString *deviceToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x", ntohl(deviceTokenBytes[0]), ntohl(deviceTokenBytes[1]), ntohl(deviceTokenBytes[2]), ntohl(deviceTokenBytes[3]), ntohl(deviceTokenBytes[4]), ntohl(deviceTokenBytes[5]), ntohl(deviceTokenBytes[6]), ntohl(deviceTokenBytes[7])]; return deviceToken; }
@结束
// AppDelegate.m
#import "NSData+DeviceToken.h" - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = deviceToken.stringDeviceToken; }
工作正常!
var token: String = "" for i in 0..<deviceToken.count { token += String(format: "%02.2hhx", deviceToken[i] as CVarArg) } print(token)
尝试这一个,除非数据是空终止的。
NSString* newStr = [[NSString alloc] initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
NSString *tokenstring = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];