How can I convert my device token (NSData) into an NSString?

后端 未结 30 1688
挽巷
挽巷 2020-11-28 18:31

I am implementing push notifications. I\'d like to save my APNS Token as a String.

- (void)application:(UIApplication *)application
didRegisterForRemoteNotif         


        
相关标签:
30条回答
  • 2020-11-28 19:17

    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:

    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()
        }
    }
    
    0 讨论(0)
  • 2020-11-28 19:18

    Use excellent category!

    // .h file

    @interface NSData (DeviceToken)
    
    - (NSString *)stringDeviceToken;
    
    @end    
    

    // .m file

    #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;
    }
    

    @end

    // AppDelegate.m

    #import "NSData+DeviceToken.h"
    
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        NSString *token = deviceToken.stringDeviceToken;
    }
    

    Works fine!

    0 讨论(0)
  • 2020-11-28 19:21

    Explanation of %02.2hhx in the high vote answer:

    • %: Introduces the x 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 with 0 on the left.
    • .2: Gives the minimum number of digits to appear for the x conversion specifier.
    • hh: Specifies that the x 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 "ffffdd"; 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:

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

    The test is as follows:

    let deviceToken = (0..<32).reduce(Data(), {$0 + [$1]})
    print(deviceToken.reduce("", {$0 + String(format: "%.2x", $1)}))
    // Print content:
    // 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
    
    0 讨论(0)
  • 2020-11-28 19:23

    This will work for you,

    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);
    
    0 讨论(0)
  • 2020-11-28 19:24

    Swift

        // 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)")
    
        }
    
    0 讨论(0)
  • 2020-11-28 19:24
    NSString *tokenstring = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];
    
    0 讨论(0)
提交回复
热议问题