如何将设备令牌(NSData)转换为NSString?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将设备令牌(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。第二个打印令牌。如何将newDeviceToken作为NSString?

答案

用这个 :

NSString * deviceTokenString = [[[[deviceToken description]
                         stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                        stringByReplacingOccurrencesOfString: @">" withString: @""] 
                       stringByReplacingOccurrencesOfString: @" " withString: @""];

NSLog(@"The generated device token string is : %@",deviceTokenString);
另一答案

Functional Swift version

一个班轮:

let hexString = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes),
count: data.length).map { String(format: "%02x", $0) }.joinWithSeparator("")

这是一个可重用且自我记录的扩展形式:

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("")被同行视为功能主人。


编辑:我将字符串($ 0,基数:16)更改为字符串(格式:“%02x”,$ 0),因为填充零所需的一位数字

(我还不知道如何将问题标记为this other one的副本,所以我刚刚发布了我的答案)

另一答案

对于Swift:

var characterSet: NSCharacterSet = NSCharacterSet( charactersInString: "<>" )
    var deviceTokenString: String = ( deviceToken.description as NSString )
    .stringByTrimmingCharactersInSet( characterSet )
    .stringByReplacingOccurrencesOfString( " ", withString: "" ) as String

println( deviceTokenString )
另一答案

在堆上扔我的答案。避免使用字符串解析;文档无法保证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()
    }
}
另一答案

我试图用格式"%02.2hhx""%02x"测试两种不同的方法

    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)

结果是减速版本最快的是"%02x"平均2.0和2.6:

deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
另一答案

高票%02.2hhxanswer的解释:

  • %:介绍x转换说明符。
  • 02:转换值的最小宽度为2.如果转换后的值的字节数少于字段宽度,则应在左侧填充0
  • .2:给出x转换说明符的最小位数。
  • hh:指定x转换说明符适用于signed char或unsigned char参数(该参数将根据整数提升进行提升,但其值应在打印前转换为signed char或unsigned char)。
  • x:无符号参数应转换为“dddd”样式的无符号十六进制格式;使用字母“abcdef”。精度指定要显示的最小位数;如果转换的值可以用较少的数字表示,则应使用前导零进行扩展。默认精度为1.使用显式精度零转换零的结果不应为字符。

有关更多详细信息,请参阅IEEE printf specification


基于上面的解释,我认为最好将%02.2hhx改为%02x%.2x

对于Swift 5,以下方法都是可行的:

deviceToken.map({String(format: "%02x", $0)}).joined()
deviceToken.map({String(format: "%.2x", $0)}).joined()
deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
deviceToken.reduce("", {$0 + String(format: "%.2x", $1)})

测试如下:

let deviceToken = (0..<32).reduce(Data(), {$0 + [$1]})
print(deviceToken.reduce("", {$0 + String(format: "%.2x", $1)}))
// Print content:
// 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
另一答案

迅速:

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

    }
另一答案

这是你在Xamarin.ios中的表现

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var tokenStringBase64 = deviceToken.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
    //now you can store it for later use in local storage
}
另一答案
-(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中这样做:

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

Edit: For Swift 3

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

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print(token)
}
另一答案

斯威夫特3:

如果有人正在寻找一种在Swift 3中获取设备令牌的方法。请使用以下修

以上是关于如何将设备令牌(NSData)转换为NSString?的主要内容,如果未能解决你的问题,请参考以下文章

如何将字符串转换为 NSData 以将其传递给 BLE 设备?

NSData类型转换成NSString类型

将UIImage转换为NSData并返回UIImage

将 NSData 转换为 NSString 后如何将 NSString 转换回 NSData?

将 CNContact 转换为 NSData,反之亦然

如何将 nsdata 转换为 MPMediaitem 歌曲 iOS Sdk