Как я могу преобразовать мой токен устройства (NSData) в строку NSString? - PullRequest
139 голосов
/ 21 февраля 2012

Я внедряю push-уведомления.Я хотел бы сохранить свой токен APNS в виде строки.

- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
    NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
    NSLog(@"%@", tokenString);
    NSLog(@"%@", newDeviceToken);
}

Первая строка кода печатает ноль.вторая печатает токен.Как я могу получить свой newDeviceToken как NSString?

Ответы [ 24 ]

1 голос
/ 05 апреля 2019

Объяснение %02.2hhx в высоком голосовании ответ :

  • %: вводит спецификатор преобразования x.
  • 02: минимальная ширина преобразованного значения равна 2. Если преобразованное значение имеет меньше байтов, чем ширина поля, оно должно быть дополнено 0 слева.
  • .2: дает минимальное количество цифр, которое должно отображаться для спецификатора преобразования x.
  • hh: указывает, что спецификатор преобразования x применяется к аргументу со знаком char или unsigned char (аргумент будет повышаться в соответствии с целочисленными акциями, но его значение должно быть преобразовано в char со знаком или unsigned char до печать).
  • x: Аргумент без знака должен быть преобразован в шестнадцатеричный формат без знака в стиле "dddd"; буквы "abcdef" используются. Точность определяет минимальное количество отображаемых цифр; если конвертируемое значение может быть представлено меньшим количеством цифр, оно должно быть расширено начальными нулями. Точность по умолчанию равна 1. Результат преобразования нуля с явной точностью нуля не должен содержать символов.

Подробнее см. В спецификации IEEE printf .


Исходя из приведенного выше объяснения, я думаю, что лучше изменить %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
1 голос
/ 12 мая 2017

Я пытался протестировать два разных метода в формате "%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)})
1 голос
/ 10 июня 2015

Для Свифта:

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

println( deviceTokenString )
1 голос
/ 28 сентября 2016

Кидаю мой ответ в груду.Избегайте использования разбора строк;Документы не гарантируют, что 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()
    }
}
0 голосов
/ 21 февраля 2012
NSString *tokenstring = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding];
0 голосов
/ 28 марта 2014
-(NSString *)deviceTokenWithData:(NSData *)data
{
    NSString *deviceToken = [[data description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    return deviceToken;
}
0 голосов
/ 17 июня 2016

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)
0 голосов
/ 04 февраля 2016

Используйте отличную категорию!

// .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;
}

@ конец

// AppDelegate.m

#import "NSData+DeviceToken.h"

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    NSString *token = deviceToken.stringDeviceToken;
}

Работает отлично!

0 голосов
/ 29 октября 2015

Свифт

    // 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 голосов
/ 02 сентября 2014
var token: String = ""
for i in 0..<deviceToken.count {
    token += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}

print(token)
...