Wdrażam powiadomienia push. Chciałbym zapisać mój token APNS jako ciąg.
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken
{
NSString *tokenString = [NSString stringWithUTF8String:[newDeviceToken bytes]]; //[[NSString alloc]initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
NSLog(@"%@", tokenString);
NSLog(@"%@", newDeviceToken);
}
Pierwsza linia kodu wypisuje wartość null. druga drukuje token. Jak mogę uzyskać mój newDeviceToken jako NSString?
ios
objective-c
apple-push-notifications
nsstring
nsdata
Sheehan Alam
źródło
źródło
NSLog
, tego, który drukujenewDeviceToken
?Odpowiedzi:
Użyj tego :
źródło
Jeśli ktoś szuka sposobu na zrobienie tego w Swift:
Edycja: dla Swift 3
Swift 3 wprowadza
Data
typ z semantyką wartości. Aby przekonwertowaćdeviceToken
ciąg na ciąg, możesz wykonać następujące czynności:źródło
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
qiita.com/mono0926/items/3cf0dca3029f32f54a09"%02.2hhx
?Ktoś mi w tym pomógł, po prostu przechodzę dalej
źródło
const unsigned *tokenBytes = [deviceToken bytes]; NSMutableString *hexToken = [NSMutableString string]; for (NSUInteger byteCount = 0; byteCount * 4 < [deviceToken length]; byteCount++) { [hexToken appendFormat:@"%08x", ntohl(tokenBytes[byteCount])]; }
Important: APNs device tokens are of variable length. Do not hard-code their size.
Apple mówi.Możesz tego użyć
źródło
description
.[token appendFormat:@"%02.2hhx", data[i]];
ponieważ Amazon SNS wymaga małych liter.Dla tych, którzy chcą w Swift 3 i najłatwiejszej metodzie
źródło
deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
Wyjaśnienie
%02.2hhx
w wysokiej głosowanie odpowiedź :%
: Wprowadza specyfikatorx
konwersji.02
: Minimalna szerokość konwertowanej wartości wynosi 2. Jeżeli przekonwertowana wartość ma mniej bajtów niż szerokość pola, należy ją dopełnić0
po lewej stronie..2
: Podaje minimalną liczbę cyfr, które mają pojawić się wx
konwersji.hh
: Określa, że specyfikatorx
konwersji ma zastosowanie do argumentu ze znakiem lub bez znaku (argument będzie promowany zgodnie z promocjami w postaci liczb całkowitych, ale jego wartość zostanie przekonwertowana na znak ze znakiem lub znak bez znaku przed wydrukowaniem).x
: Argument bez znaku zostanie przekonwertowany na format szesnastkowy bez znaku w stylu „dddd”; używane są litery „abcdef”. Precyzja określa minimalną liczbę cyfr, które mają się pojawić; jeżeli przekształcaną wartość można przedstawić za pomocą mniejszej liczby cyfr, należy ją rozszerzyć o zera na początku. Domyślna dokładność wynosi 1. Wynik konwersji zera z wyraźną precyzją zera nie może zawierać żadnych znaków.Więcej informacji można znaleźć w specyfikacji IEEE printf .
Na podstawie powyższego wyjaśnienia myślę, że lepiej zmienić
%02.2hhx
na%02x
lub%.2x
.W przypadku Swift 5 możliwe są wszystkie następujące metody:
Test wygląda następująco:
źródło
To moje rozwiązanie i działa dobrze w mojej aplikacji:
NSData
naNSString
zstringWithFormat
źródło
-description
, więc nie jest bezpieczniejsze niż zaakceptowana odpowiedź.description
deviceToken, jak mówi jszumski.description
czy wywołasz go bezpośrednio, czy użyjesz go inną metodą, ponieważ format zwracanego ciągu można zmienić w dowolnym momencie. Prawidłowe rozwiązanie jest tutaj: stackoverflow.com/a/16411517/108105Myślę, że konwersja deviceToken na ciąg bajtów szesnastkowych nie ma sensu. Czemu? Wyślesz go do swojego zaplecza, gdzie zostanie przekształcony z powrotem w bajty do przekazania do APNS. Tak więc, użyj metody NSData
base64EncodedStringWithOptions
, wypchnij ją na serwer, a następnie użyj odwrotnych danych dekodowanych base64 :) To jest o wiele łatwiejsze :)źródło
W iOS 13
description
się zepsuje, więc użyj tegoDla jasności podzielmy to i wyjaśnijmy każdą część:
Metoda map działa na każdym elemencie sekwencji. Ponieważ Data jest sekwencją bajtów w Swift, przekazane zamknięcie jest oceniane dla każdego bajtu w deviceToken. Inicjator String (format :) ocenia każdy bajt w danych (reprezentowany przez anonimowy parametr $ 0) przy użyciu specyfikatora formatu% 02x w celu utworzenia dwucyfrowej, szesnastkowej reprezentacji bajtu / 8-bitowej liczby całkowitej z zerami. Po zebraniu każdej reprezentacji bajtowej utworzonej przez metodę map, join () łączy każdy element w jeden ciąg.
PS nie używaj opisu daje inny ciąg w iOS 12 i iOS 13 i nie jest bezpieczny w przyszłym zakresie. Programiści nie powinni polegać na określonym formacie opisu obiektu.
Aby uzyskać więcej informacji, przeczytaj This .
źródło
W iOS 13 opis będzie miał inny format. Użyj poniższego kodu, aby pobrać token urządzenia.
źródło
length
w pętli for należy zmienić nalen
. Najwyraźniej zbyt mała zmiana, abym mógł dokonać edycji .. Ale poza tym działa idealnie!To jest trochę krótsze rozwiązanie:
źródło
Funkcjonalna wersja Swift
Jedna wkładka:
Oto rozszerzenie do wielokrotnego użytku, samodokumentujące się:
Alternatywnie, użyj
reduce("", combine: +)
zamiastjoinWithSeparator("")
być postrzeganym przez rówieśników jako wzorzec funkcjonalny.Edycja: Zmieniłem String ($ 0, radix: 16) na String (format: "% 02x", $ 0), ponieważ liczby jednocyfrowe potrzebne do wypełnienia zerami
(Jeszcze nie wiem, jak oznaczyć pytanie jako duplikat tego drugiego , więc ponownie opublikowałem odpowiedź)
źródło
2020
token jako tekst ...
lub jeśli wolisz
(wynik jest taki sam)
źródło
Rzucam moją odpowiedź na stos. Unikaj analizowania ciągów; Dokumentacja nie gwarantuje, że NSData.description zawsze będzie działać w ten sposób.
Wdrożenie Swift 3:
źródło
Próbowałem przetestować dwie różne metody z formatami
"%02.2hhx"
i"%02x"
a wynik jest taki, że najszybsza jest
"%02x"
średnia 2,0 vs 2,6 dla wersji zredukowanej:źródło
Korzystanie z metody updateAccumulatingResult jest bardziej wydajne niż różne inne podejścia, które można znaleźć tutaj, więc oto najszybszy sposób na zdefiniowanie
Data
bajtów:źródło
Dla Swift:
źródło
A co z rozwiązaniem jednoprzewodowym?
Cel C
Szybki
źródło
Oto, jak to zrobić w Xamarin.iOS
źródło
źródło
Szybki:
źródło
źródło
Szybki
źródło
Użyj doskonałej kategorii!
// plik .h
// plik .m
@koniec
// AppDelegate.m
Działa w porządku!
źródło
Swift 3:
Jeśli ktoś szuka sposobu na zdobycie tokena urządzenia w Swift 3. Użyj poniższego zmodyfikowanego fragmentu.
źródło
źródło
Opublikowane tutaj rozwiązanie @kulss, choć brakuje mu elegancji, ale ma cnotę prostoty, nie działa już w iOS 13, ponieważ
description
będzie działać inaczej dla NSData. Nadal możesz używaćdebugDescription
.źródło
Spróbuj tego, chyba że dane są zakończone wartością null.
NSString* newStr = [[NSString alloc] initWithData:newDeviceToken encoding:NSUTF8StringEncoding];
źródło
źródło