2009-10-19 14 views
33

Ricevo un token dispositivo iPhone sotto forma di oggetto NSData. Quando ho testato la funzione di script delle notifiche, ho solo copiato quell'oggetto dal registro e le notifiche sono andate bene. Tuttavia quando provo subito a farlo automaticamente, io mando il token dispositivo ASCII stringa codificata in forma di variabiliToken dispositivo Iphone - NSData o NSString

self.deviceToken = [[NSString alloc] initWithData:webDeviceToken encoding:NSASCIIStringEncoding]; 

La stringa che sto ottenendo ha alcuni caratteri funky ed è simile a questo "å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

Quando lo script lato server invia la notifica a quel token, non ricevo nulla.

Devo decodificare qualcosa e come?

Regardz

+0

ho trovato qui un'altra soluzione, sembra più a prova di futuro, allora il metodo "descrizione". http://stackoverflow.com/questions/1959600/how-to-use-objective-c-to-send-device-token-for-push-notifications-and-other-use –

+0

Questo è strano, penso che questo NSData * non dovrebbe essere un oggetto di tipo speciale, quindi ho provato a utilizzare NSUTF8StringEncoding e ottenere un risultato diverso. Per me è inimmaginabile convertire NSData in NSString con il metodo ** description **! Qualche documentazione relativa alla mela? – Itachi

risposta

107

Ok, ho trovato una soluzione. Se qualcuno ha lo stesso problema, dimenticare la codifica ASCII, basta fare la stringa con le seguenti righe:

NSString *deviceToken = [[webDeviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; 
deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""]; 
+7

Si prega di interrompere la risposta, questa usa il token .description, che è solo una descrizione. È pensato per essere letto da un essere umano per scopi di debug o visualizzazione. "<" and ">" non fanno parte del token, sono solo per la formattazione della visualizzazione. Apple potrebbe cambiarlo in "[" o "-" o qualsiasi altra cosa in futuro, se lo volessero. Utilizzare una delle risposte che converte i dati in una stringa esadecimale. –

2

non credo che sia una buona soluzione, come si deve ricostruire la stringa prima di inviare le notifiche di Server Apple Usa la codifica Base64 per trasmettere le stringhe o qualcosa di simile.

+0

La stringa inviata funziona dal lato server senza alcuna ricostruzione o modifica – Mladen

+0

Ma per quanto vedo, si stanno rimuovendo e tagliando i caratteri ... Hai provato a inviare notifiche usando quel token e ha funzionato? Come mai? –

+0

Ho provato e ha funzionato. – Mladen

5

Ho trovato questa soluzione migliore in quanto iOS può modificare l'utilizzo della descrizione nelle versioni future, quindi l'utilizzo della proprietà di descrizione sui dati può non essere affidabile in futuro. Possiamo direttamente utilizzarlo creando un token esadecimale dai byte del token di dati.

- (void)application:(UIApplication *)app 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]; 

}

Possiamo anche memorizzare il token dispositivo nei nostri NSUserDefaults e utilizzarla in seguito per inviare fuori al nostro server.

0

Un altro modo di convertire gettone dispositivo in hexa stringa decimale

NSUInteger capacity = [deviceToken length] * 2; 
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:capacity]; 
const unsigned char *dataBuffer = [deviceToken bytes]; 
NSInteger i; 
for (i=0; i<[deviceToken length]; ++i) { 
    [stringBuffer appendFormat:@"%02X", (NSUInteger)dataBuffer[i]]; 
} 
NSLog(@"token string buffer is %@",stringBuffer); 
43

Se qualcuno è alla ricerca di un modo per fare questo in 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)") 
} 

Edit: Per Swift 3

Swift 3 introduce il tipo Data, con la semantica del valore.Per convertire il deviceToken ad una stringa, si può fare come segue:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 

    var token: String = "" 
    for i in 0..<deviceToken.count { 
     token += String(format: "%02.2hhx", deviceToken[i] as CVarArg) 
    } 

    print(token) 
} 
+0

Thx! Esattamente quello di cui ho bisogno! – kimimaro

+1

Sorprende che non vi sia un modo semplice per ottenere i dati di stringa opportunamente decodificati dall'oggetto token del dispositivo NSData. Ma questo è un esempio per @sascha è la prima cosa che ho trovato che funzioni davvero! Grazie. – Shiprack

+1

Ora spostalo sull'estensione NSData e chiamalo 'hexadecimalStringDescription()' – Eimantas

0

Per Swift 3:

var tokenString: String = "" 
    for i in 0..<deviceToken.count { 
     tokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg) 
    } 

    print(tokenString) 

altri Metodo

Creare un'estensione dei dati per ottenere hexstring

extension Data { 
    var hexString: String { 
     return map { String(format: "%02.2hhx", arguments: [$0]) }.joined() 
    } 
} 

E non chiamate questa estensione in

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
    let tokenString = deviceToken.hexString() 
    print("token: \(tokenString)") 
} 
+0

Questo funziona per Swift 2.0. Grazie. –

+0

Non fare affidamento su .description, il formato che si ottiene non è documentato e potrebbe cambiare tecnicamente. deviceToken.description deve essere utilizzato solo a scopo di debug. Utilizzare una delle risposte che converte i byte in una stringa esadecimale. –

+2

concordato. Non usare questo. Quando si utilizza PKPushCredentials, la descrizione restituisce "32 byte" – Tony