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

Ios 如何将设备令牌(NSData)转换为NSString?,ios,objective-c,apple-push-notifications,nsstring,nsdata,Ios,Objective C,Apple Push Notifications,Nsstring,Nsdata,我正在实现推送通知。我想将我的APNS令牌保存为字符串 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken { NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[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);
}

第一行代码打印空值。第二个打印令牌。我怎样才能让我的新设备成为一个NSString呢?

有人帮了我这个忙。我只是路过而已

- (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];
}

请尝试此选项,除非数据以null结尾

NSString*newStr=[[NSString alloc]initWithData:newDeviceToken

编码:NSUTF8StringEncoding]

注意-使用iOS 13或更高版本的SDK编译时,这将不起作用

使用以下命令:

NSString * deviceTokenString = [[[[deviceToken description]
                         stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                        stringByReplacingOccurrencesOfString: @">" withString: @""] 
                       stringByReplacingOccurrencesOfString: @" " withString: @""];
        
NSLog(@"The generated device token string is : %@",deviceTokenString);
NSString*DeviceTokennstring=[[[deviceToken描述]
StringByReplacingOfString:@“with String:@”]
StringByReplacingOfString:@“和字符串:@]”发生;
NSLog(@“生成的设备令牌字符串为:%@”,deviceTokenString);
您可以使用此

- (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];
}
-(NSString*)stringWithDeviceToken:(NSData*)deviceToken{
常量字符*数据=[deviceToken字节];
NSMutableString*标记=[NSMutableString];
对于(整数i=0;i<[deviceToken length];i++){
[令牌格式:@“%02.2hhX”,数据[i]];
}
返回[令牌副本];
}

这是我的解决方案,在我的应用程序中运行良好:

    NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken] 
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
NSString*newToken=[[NSString stringWithFormat:@“%@”,deviceToken]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@”“]]StringByReplacingOfString:@”“with String:@”“]的发生率;
  • 使用
    stringWithFormat
  • 修剪“”
  • 删除空格
-(NSString*)设备,带有数据:(NSData*)数据
{
NSString*deviceToken=[[数据描述]stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@”“];
deviceToken=[deviceToken StringByReplacingOfString:@“with String:@”的发生率];
返回装置停止;
}

如果有人想在Swift中实现这一点:

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

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print(token)
}
let deviceToken = (0..<32).reduce(Data(), {$0 + [$1]})
print(deviceToken.reduce("", {$0 + String(format: "%.2x", $1)}))
// Print content:
// 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
使用
NSData
的旧答案:

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)")
}
func应用程序(应用程序:UIApplication,didRegisterForRemotionTificationswithDeviceToken deviceToken:NSData){
让tokenChars=UnsafePointer(deviceToken.bytes)
var tokenString=“”
对于0中的i..
var标记:String=“”

对于0..中的i,这是一个略短的解决方案:

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])];
NSString*tokenString=[[newDeviceToken description]stringByReplacingOccurrencesOfString:@“[]”带字符串:@“选项:NSRegularExpressionSearch范围:NSMakeRange(0,[[newDeviceToken description]length]);
对于Swift:

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

println( deviceTokenString )
var characterSet:NSCharacterSet=NSCharacterSet(charactersInString:)
变量deviceTokenString:String=(deviceToken.description作为NSString)
.StringByTrimming字符集(字符集)
.StringByReplacingOfString(“,带字符串:“”)作为字符串
println(设备安装)
Swift:

let tokenString = deviceToken.description.stringByReplacingOccurrencesOfString("[ <>]", withString: "", options: .RegularExpressionSearch, range: nil)
let tokenString=deviceToken.description.stringByReplacingOccurrencesOfString([]),带字符串:“”,选项:。RegularExpressionSearch,范围:nil)

我认为将deviceToken转换为十六进制字节字符串没有意义。为什么?您将把它发送到后端,在那里它将被转换回字节以推送到APN。因此,使用NSData的方法
base64EncodedStringWithOptions
,将它推送到服务器,然后使用reverse base64解码数据:),这就容易多了:)


单线解决方案怎么样

目标C

NSString *token = [[data.description componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet]invertedSet]]componentsJoinedByString:@""];
迅捷的

迅捷的

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

    }
//确保我们在应用程序上有设备的令牌
func应用程序(应用程序:UIApplication
,DidRegisterForRemotonificationswithDeviceToken deviceToken:NSData){
var tokenStr=deviceToken.description
tokenStr=tokenStr.stringByReplacingOccurrencesOfString(“,带字符串:”,选项:[],范围:nil)
tokenStr=tokenStr.stringByReplacingOccurrencesOfString(“,带字符串:”,选项:[],范围:nil)
打印(“我的令牌是:\(tokenStr)”)
}

使用优秀类别

//.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;
}
工作正常!

功能性Swift版本 一艘班轮:

let hexString = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes),
count: data.length).map { String(format: "%02x", $0) }.joinWithSeparator("")
let hexString=UnsafeBufferPointer(开始:UnsafePointer(data.bytes),
count:data.length).map{String(格式:'%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("")
    }
}
扩展数据{ func base16EncodedString(大写:Bool=false)->字符串{ let buffer=UnsafeBufferPointer(开始:UnsafePointer(self.bytes)), 计数:自我长度) 设hexFormat=大写?“X”:“X” let formatString=“%02\(hexFormat)” 让bytesAsHexStrings=buffer.map{ 字符串(格式:formatString,$0) } 返回bytesAsHexStrings.joinWithSeparator(“”) } }

或者,使用
reduce(“,combine:+)
而不是
joinWithSeparator(“”)
,以使您的同行将其视为功能主机


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


(我还不知道如何将问题标记为的副本,所以我只是再次发布了我的答案)

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)
let characterSet:characterSet=characterSet(charactersIn:)
让deviceTokenString:String=(deviceToken.description作为NSString)
.trimmingCharacters(在:characterSet中作为characterSet
#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;
}
#import "NSData+DeviceToken.h"

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSString *token = deviceToken.stringDeviceToken;
}
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("")
    }
}
    let characterSet: CharacterSet = CharacterSet( charactersIn: "<>" )

    let deviceTokenString: String = (deviceToken.description as NSString)
        .trimmingCharacters(in: characterSet as CharacterSet)
        .replacingOccurrences(of: " ", with: "")
        .uppercased()

    print(deviceTokenString)
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()
    }
}
func extractTokenFromData(deviceToken:Data) -> String {
    let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    return token.uppercased();
}
    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)
deviceToken.reduce("", {$0 + String(format: "%02x", $1)})
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
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 * deviceTokenString = [[[[deviceToken debugDescription]
                     stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                    stringByReplacingOccurrencesOfString: @">" withString: @""] 
                   stringByReplacingOccurrencesOfString: @" " withString: @""];
let deviceTokenString = deviceToken.map { String(format: "%02x", $0) }.joined()
// iOS 12
(deviceToken as NSData).description // "<965b251c 6cb1926d e3cb366f dfb16ddd e6b9086a 8a3cac9e 5f857679 376eab7C>"

// iOS 13
(deviceToken as NSData).description // "{length = 32, bytes = 0x965b251c 6cb1926d e3cb366f dfb16ddd ... 5f857679 376eab7c }"
- (NSString *)fetchDeviceToken:(NSData *)deviceToken {
    NSUInteger len = deviceToken.length;
    if (len == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(len * 2)];
    for (int i = 0; i < len; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }
    return [hexString copy];
}
let tat = deviceToken.map{ data in String(format: "%02.2hhx", data) }.joined()
let tat2 = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
NSUInteger dataLength = deviceToken.length;
    
const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
NSMutableString *deviceTokenString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for (int i = 0; i < dataLength; ++i) {
    [deviceTokenString appendFormat:@"%02x", dataBuffer[i]];
}
    
NSLog(@"The generated device token string is : %@",deviceTokenString);