Как преобразовать токен устройства (NSData) в NSString?

Я внедряю 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?

4b9b3361

используйте это:

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

NSLog(@"The generated device token string is : %@",deviceTokenString);
64
ответ дан 21 февр. '12 в 8:52
источник

Если кто-то ищет способ сделать это в 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 со значениями семантики. Чтобы преобразовать deviceToken в строку, вы можете сделать следующее:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print(token)
}
191
ответ дан 27 июля '14 в 13:17
источник

Кто-то помог мне с этим. Я просто прохожу

- (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];
}
153
ответ дан 21 февр. '12 в 8:51
источник

Вы можете использовать этот

- (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];
}
94
ответ дан 07 мая '13 в 8:01
источник

Для тех, кто хочет в Swift 3 и наиболее удобном методе

func extractTokenFromData(deviceToken:Data) -> String {
    let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    return token.uppercased();
}
34
ответ дан 05 окт. '16 в 14:05
источник

Это мое решение, и оно хорошо работает в моем приложении:

    NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken] 
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
  • конвертировать NSData в NSString с помощью stringWithFormat
  • нарисуйте "< > "
  • удалить пробелы
16
ответ дан 10 янв. '14 в 17:29
источник

Я думаю, что преобразование deviceToken в шестнадцатеричную байтовую строку не имеет смысла. Зачем? Вы отправите его на свой сервер, где он будет преобразован обратно в байты, которые будут перенесены в APNS. Итак, используйте NSData​​strong > метод base64EncodedStringWithOptions, нажмите его на сервер, а затем используйте обратные данные с базовым 64-разрядным кодом:) Это намного проще:)

NSString *tokenString = [tokenData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
5
ответ дан 03 сент. '15 в 14:49
источник

Это немного более короткое решение:

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])];
4
ответ дан 21 окт. '14 в 0:25
источник

Функциональная версия Swift

Один вкладыш:

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("") для просмотра в качестве функционального мастера вашими сверстниками.


Изменить: я изменил String ($ 0, radix: 16) на String (формат: "% 02x", $0), потому что для одного номера цифр необходимо иметь нулевой пробел

(Я еще не знаю, как отметить вопрос как дубликат этого другого, поэтому я только что отправил свой ответ снова)

3
ответ дан 01 марта '16 в 21:19
источник

Как насчет решения одной строки?

Цель C

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

Свифта

let token = data.description.componentsSeparatedByCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet).joinWithSeparator("")
3
ответ дан 07 окт. '15 в 9:34
источник

Бросив мой ответ на кучу. Избегайте использования синтаксического анализа строк; Это не гарантирует документы, что 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()
    }
}
1
ответ дан 28 сент. '16 в 21:20
источник

Для Swift:

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

println( deviceTokenString )
1
ответ дан 10 июня '15 в 12:02
источник

Я попытался протестировать два разных метода с помощью формата "%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)})
0
ответ дан 12 мая '17 в 13:02
источник

Swift:

let tokenString = deviceToken.description.stringByReplacingOccurrencesOfString("[ <>]", withString: "", options: .RegularExpressionSearch, range: nil)
0
ответ дан 31 июля '15 в 9:58
источник

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
ответ дан 29 окт. '15 в 12:41
источник
NSString *tokenString = [[newDeviceToken description] stringByReplacingOccurrencesOfString:@"[<> ]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [[newDeviceToken description] length])];
-1
ответ дан 07 нояб. '14 в 13:23
источник

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)
-1
ответ дан 17 июня '16 в 0:27
источник
-(NSString *)deviceTokenWithData:(NSData *)data
{
    NSString *deviceToken = [[data description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    return deviceToken;
}
-1
ответ дан 28 марта '14 в 14:46
источник

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

//.h файл

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

Прекрасно работает!

-2
ответ дан 04 февр. '16 в 10:51
источник
var token: String = ""
for i in 0..<deviceToken.count {
    token += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}

print(token)
-3
ответ дан 02 сент. '14 в 16:37
источник

Попробуйте выполнить это, если данные не завершены нулями.

NSString* newStr = [[NSString alloc] initWithData:newDeviceToken encoding:NSUTF8StringEncoding];

-6
ответ дан 21 февр. '12 в 8:52
источник