2009-10-19 19 views
33

estoy recibiendo token de dispositivo iPhone en forma de NSData objeto. Cuando probé la función del script de notificaciones, solo copié ese objeto del registro y las notificaciones fueron bien. Sin embargo cuando intento ahora para hacer automáticamente, estoy enviando la ficha Dispositivo cadena codificada ASCII en forma de variablesIphone token de dispositivo - NSData o NSString

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

La cadena que me estoy haciendo tiene algunos caracteres extraños y tiene una apariencia similar a esta "å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

Cuando script del lado del servidor envía la notificación a esa señal, no recibo nada.

¿Es necesario decodificar algo y cómo?

Regardz

+0

he encontrado otra solución a este problema, se parece más a prueba de futuro, entonces el método de la "descripción". http://stackoverflow.com/questions/1959600/how-to-use-objective-c-to-send-device-token-for-push-notifications-and-other-use –

+0

Esto es extraño, creo que este NSData * no debería ser un objeto tipo especial, así que traté de usar NSUTF8StringEncoding y obtuve un resultado diferente. ¡Es inimaginable para mí convertir NSData en NSString con el método de ** descripción **! ¿Alguna documentación de manzana relacionada? – Itachi

Respuesta

107

Bien, encontré una solución. Si alguien tiene el mismo problema, olvidarse de codificación ASCII, acaba de hacer la cadena con las siguientes líneas:

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

Por favor, deje de votar esta respuesta, esto usa el token .description, que es solo eso, una descripción. Está destinado a ser leído por un ser humano para fines de depuración o visualización. Los "<" and ">" no son parte del token, solo son para el formato de visualización. Apple podría cambiarlo a "[" o "-" o lo que sea en el futuro si así lo desean. Use una de las respuestas que convierte los datos a una cadena hexadecimal en su lugar. –

2

no creo que es una buena solución, ya que hay que reconstruir la cadena antes de enviar las notificaciones a Servidores de Apple. Use la codificación Base64 para transmitir las cadenas o algo similar.

+0

La cadena enviada funciona desde el lado del servidor sin reconstrucciones o modificaciones – Mladen

+0

Pero, por lo que veo, está eliminando y recortando caracteres ... ¿Intentó enviar notificaciones utilizando ese token y funcionó? ¿Cómo? –

+0

Lo he intentado y funcionó. – Mladen

5

He encontrado esta solución mejor como IOS puede cambiar el uso de la descripción en futuras versiones, por lo que el uso de descripción de la propiedad en los datos pueden ser poco fiables en el futuro. Podemos usar esto directamente creando un Token hexadecimal a partir de los bytes del token de datos.

- (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]; 

}

También podemos almacenar el token necesario en la NSUserDefaults y utilizarla más tarde para enviarlo a nuestro servidor.

0

Otra manera de convertir token de dispositivo en hexa cadena decimal

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

Si alguien está buscando una manera de hacer esto en 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)") 
} 

Editar: Para Swift 3

Swift 3 introduce el tipo Data, con semántica de valores.Para convertir el deviceToken a una cadena, puede hacerlo de la siguiente manera:

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! ¡Exactamente lo que necesito! – kimimaro

+1

Es sorprendente que no haya una manera fácil de obtener rápidamente los datos de cadena descodificados apropiadamente del objeto token del dispositivo NSData. ¡Pero este es el ejemplo de fro @sascha que es lo primero que he encontrado que realmente funciona! Gracias. – Shiprack

+1

Ahora muévala a la extensión NSData y llámala 'hexadecimalStringDescription()' – Eimantas

0

Para Swift 3:

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

    print(tokenString) 

otro método

Crear extensión Data para obtener HexString

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

Y llamar a esta extensión en

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

Esto funciona para Swift 2.0. Gracias. –

+0

No confíe en .description, el formato que obtiene no está documentado y podría cambiar técnicamente. deviceToken.description solo debe usarse para fines de depuración. Use una de las respuestas que convierte los bytes a una cadena hexadecimal en su lugar. –

+2

de acuerdo. No uses esto Al utilizar PKPushCredentials, la descripción ahora devuelve "32 bytes" – Tony

Cuestiones relacionadas