Obtener token de dispositivo para notificaciones push

84

Estoy trabajando en notificaciones automáticas. Escribí el siguiente código para obtener un token de dispositivo.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    NSLog(@"Registering for push notifications...");    
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

    return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
    NSLog(@"This is device token%@", deviceToken);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
    NSString *str = [NSString stringWithFormat: @"Error: %@", err];
    NSLog(@"Error %@",err);    
}

Puedo ejecutar la aplicación en el dispositivo correctamente, pero no puedo obtener la identificación del dispositivo en la consola.

No tengo problemas con la certificación y los perfiles de aprovisionamiento.

jagzzz
fuente
¿Seguiste todos los pasos ? Si no tiene ningún problema con la certificación y la provisión, así como con el código, entonces debe estar cometiendo un pequeño error. Como ... dime, ¿estás ejecutando la aplicación en un dispositivo real adjuntando lo mismo con tu sistema? ¿También está notando si está obteniendo el token del dispositivo en el registro de la consola o no? ¿Ha habilitado la notificación Push en iPhone ?
Sarah
No puedo obtener el token del dispositivo en el registro de la consola.
jagzzz
Estoy ejecutando la aplicación en un dispositivo real sin ningún error.
jagzzz
¿Habilitó APNS como se muestra en el enlace en el iPhone?
Sarah
sí, habilité APNS ... pero el token del dispositivo no se puede recuperar en cosole
jagzzz

Respuestas:

162

NOTA: La siguiente solución ya no funciona en dispositivos iOS 13+; devolverá datos basura .

En su lugar, utilice el siguiente código:

+ (NSString *)hexadecimalStringFromData:(NSData *)data
{
  NSUInteger dataLength = data.length;
  if (dataLength == 0) {
    return nil;
  }

  const unsigned char *dataBuffer = (const unsigned char *)data.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  return [hexString copy];
}

Solución que funcionó antes de iOS 13:

C objetivo

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"this will return '32 bytes' in iOS 13+ rather than the token", token);
} 

Swift 3.0

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("this will return '32 bytes' in iOS 13+ rather than the token \(tokenString)")
}
Wasif Saood
fuente
4
Luego, verifique su perfil de aprovisionamiento, debe ser el ID de la aplicación con el que ha creado su certificado SSL para notificaciones push.
Wasif Saood
1
debe agregar el código en el archivo AppDelegate @jagzzz
codercat
2
Para aquellos interesados ​​en un ejemplo de código escrito en Swift: gist.github.com/sawapi/a7cee65e4ad95578044d
Benjamin
3
Cuidado, el uso de la propiedad "description" ya no funciona: stackoverflow.com/questions/39495391/…
hariseldon78
1
@codester Había subido mi compilación usando Xcode 10.3 y está en vivo. Según su declaración, el método Objective C se romperá en adelante con XCode 11, pero lo que puedo ver en nuestra base de datos muestra la longitud de los datos en lugar de una cadena correcta de token apns. Así que solo quiero saber eso, ¿depende de la versión de Xcode o de la versión de iOS (es decir, 13. *)?
pradip sutariya
13

Para obtener Token Device, puede seguir algunos pasos :

1) Habilite APNS (Apple Push Notification Service) tanto para la Certificación de desarrollador como para la Certificación de distribución, luego vuelva a descargar esos dos archivos.

2) Vuelva a descargar el archivo de aprovisionamiento de desarrollador y de aprovisionamiento distribuido.

3) En la interfaz Xcode: la configuración del aprovisionamiento para PROJECT y TARGETS con dos archivos de aprovisionamiento tiene descarga.

4) Finalmente, debe agregar el código a continuación en el archivo AppDelegate para obtener Token Device (nota: ejecutar la aplicación en el dispositivo real).

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
     [self.window addSubview:viewController.view];
     [self.window makeKeyAndVisible];

     NSLog(@"Registering for push notifications...");    
     [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
 (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
     return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
     NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
     NSLog(@"%@", str);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
     NSString *str = [NSString stringWithFormat: @"Error: %@", err];
     NSLog(@"%@",str);
}
Bkillnest
fuente
11

Usar descriptiontantas de estas respuestas sugiere que es el enfoque incorrecto , incluso si lo hace funcionar, se romperá en iOS 13+.

En su lugar, debe asegurarse de utilizar los datos binarios reales, no simplemente una descripción de los mismos. Andrey Gagan abordó la solución Objective C bastante bien, pero afortunadamente es mucho más simple en rápido:

Swift 4.2 funciona en iOS 13+

// credit to NSHipster (see link above)
// format specifier produces a zero-padded, 2-digit hexadecimal representation
let deviceTokenString = deviceToken.map { String(format: "%02x", $0) }.joined()
cdstamper
fuente
7

Objective C para iOS 13+ , cortesía de la respuesta de Wasif Saood

Copie y pegue el código siguiente en AppDelegate.m para imprimir el token APN del dispositivo.

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  NSUInteger dataLength = deviceToken.length;
  if (dataLength == 0) {
    return;
  }
  const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  NSLog(@"APN token:%@", hexString);
}
Jake Cronin
fuente
5

El siguiente código se utiliza para recuperar el token del dispositivo.

    // Prepare the Device Token for Registration (remove spaces and < >)
    NSString *devToken = [[[[deviceToken description] 
                            stringByReplacingOccurrencesOfString:@"<"withString:@""] 
                           stringByReplacingOccurrencesOfString:@">" withString:@""] 
                          stringByReplacingOccurrencesOfString: @" " withString: @""];


    NSString *str = [NSString 
                     stringWithFormat:@"Device Token=%@",devToken];
    UIAlertView *alertCtr = [[[UIAlertView alloc] initWithTitle:@"Token is " message:devToken delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
    [alertCtr show];
    NSLog(@"device token - %@",str);
Nimit Parekh
fuente
2
Ésta nunca ha sido la solución correcta. Nunca base nada en el description.
rmaddy
5

Y la versión Swift de la respuesta de Wasif:

Rápido 2.x

var token = deviceToken.description.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
token = token.stringByReplacingOccurrencesOfString(" ", withString: "")
print("Token is \(token)")

Actualización para Swift 3

let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
Antoine
fuente
Nunca lo use descriptionen datos binarios (vea cualquier otra respuesta)
cdstamper
4

Si aún no obtiene el token del dispositivo, intente poner el siguiente código para registrar su dispositivo para la notificación automática.

También funcionará en ios8 o más.

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000

    if ([UIApplication respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound
                                                                                 categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         UIRemoteNotificationTypeBadge |
         UIRemoteNotificationTypeAlert |
         UIRemoteNotificationTypeSound];

    }
#else
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     UIRemoteNotificationTypeBadge |
     UIRemoteNotificationTypeAlert |
     UIRemoteNotificationTypeSound];

#endif
Nilesh
fuente
3

A partir de iOS 13, Apple ha cambiado de [deviceToken description]salida. Ahora es así, {length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc}que es incorrecto para el token del dispositivo.

Sugiero usar este fragmento de código para resolver un problema:

+ (NSString *)stringFromDeviceToken:(NSData *)deviceToken {
    NSUInteger length = deviceToken.length;
    if (length == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(length * 2)];
    for (int i = 0; i < length; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }
    return [hexString copy];
}

Funcionará para iOS13 y versiones anteriores.

Andrey Gagan
fuente
1
Para su información, cualquier respuesta que se haya utilizado descriptionsiempre fue incorrecta. Y esta es solo una posible solución para convertir el token en una cadena. Una solución mucho más simple es convertir el NSDataa una NSStringcodificación base64 estándar.
rmaddy
1

Obtener token de dispositivo en Swift 3

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

    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

    print("Device token: \(deviceTokenString)")

}
Sedat Y
fuente
1

En su AppDelegate, en el didRegisterForRemoteNotificationsWithDeviceTokenmétodo:

Actualizado para Swift:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print("\(deviceToken.reduce("") { $0 + String(format: "%02.2hhx", arguments: [$1]) })")
}
vfn
fuente
0

Swift 4 Esto funciona para mí:

Paso 1 en OBJETIVOS Haga clic en agregar capacidad y seleccione Notificaciones automáticas

Paso 2 en AppDelegate.swift agregue el siguiente código:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound]) { (didAllow, error) in
            
        }
        UIApplication.shared.registerForRemoteNotifications()
        
        return true
    }
    
    //Get device token
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
    {
        let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
        
        print("The token: \(tokenString)")
    }
James Ryan
fuente
-1

En una configuración de compilación, establezca el perfil de provisión de firma de código si tiene el certificado APN Enable, definitivamente obtendrá la identificación del token. y quitar

Perfil de suministro: automático

y establecer en

Perfil de provisión: su certificado de perfil de provisión.

Kalpesh
fuente
-1
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let tokenParts = deviceToken.map { data -> String in
        return String(format: "%02.2hhx", data)
        }
    let token = tokenParts.joined()

    print("Token\(token)")
}
Amit Gupta
fuente
-4

Para obtener el token del dispositivo, use el siguiente código, pero puede obtener el token del dispositivo solo usando un dispositivo físico. Si es obligatorio enviar el token del dispositivo, mientras usa el simulador, puede poner la siguiente condición.

  if(!(TARGET_IPHONE_SIMULATOR))
    {
        [infoDict setValue:[[NSUserDefaults standardUserDefaults] valueForKey:@"DeviceToken"] forKey:@"device_id"];
    }
    else
    {
        [infoDict setValue:@"e79c2b66222a956ce04625b22e3cad3a63e91f34b1a21213a458fadb2b459385" forKey:@"device_id"];
    }



- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    NSLog(@"My token is: %@", deviceToken);
    NSString * deviceTokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""]   stringByReplacingOccurrencesOfString: @" " withString: @""];
    NSLog(@"the generated device token string is : %@",deviceTokenString);
    [[NSUserDefaults standardUserDefaults] setObject:deviceTokenString forKey:@"DeviceToken"];
}
Yash
fuente