Ottieni il token del dispositivo per la notifica push


84

Sto lavorando alle notifiche push. Ho scritto il seguente codice per recuperare un token del 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);    
}

Sono in grado di eseguire correttamente l'applicazione sul dispositivo ma non riesco a ottenere l'ID del dispositivo sulla console.

Non ho problemi con i profili di certificazione e provisioning.


Hai seguito tutti i passaggi ? Se non hai alcun problema con la certificazione, la fornitura e il codice, devi fare un piccolo errore. Tipo ... dimmi, stai eseguendo l'app su un dispositivo reale collegando lo stesso al tuo sistema? Inoltre stai notando se stai ricevendo il token del dispositivo nel log della console o no? Hai abilitato la notifica push su iPhone ?
Sarah

Non riesco a ottenere il token del dispositivo nel registro della console.
jagzzz

Sto eseguendo l'app sul dispositivo reale senza alcun errore.
jagzzz

Hai abilitato APNS come mostrato nel link su iPhone?
Sarah

sì, ho abilitato APNS ... ma il token del dispositivo non è in grado di recuperare su cosole
jagzzz

Risposte:


163

NOTA: la soluzione seguente non funziona più sui dispositivi iOS 13+: restituirà dati inutili .

Utilizzare invece il seguente codice:

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

Soluzione che funzionava prima di iOS 13:

Obiettivo-C

- (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)")
}

4
Quindi controlla il tuo profilo di provisioning, dovrebbe essere dell'ID app con cui hai creato il tuo certificato SSL per la notifica push.
Wasif Saood

1
è necessario aggiungere il codice nel file AppDelegate @jagzzz
codercat

2
Per chi fosse interessato a un esempio di codice scritto in Swift: gist.github.com/sawapi/a7cee65e4ad95578044d
Benjamin

3
Attenzione, utilizzando la "descrizione" proprietà non funziona più: stackoverflow.com/questions/39495391/...
hariseldon78

1
@codester Avevo caricato la mia build utilizzando Xcode 10.3 ed è live. Secondo la tua affermazione, il metodo Objective C verrà interrotto in XCode 11 ma quello che posso vedere nel nostro database mostra la lunghezza dei dati invece di una stringa corretta di token apns. Quindi voglio solo sapere che, dipende dalla versione di Xcode o dalla versione iOS (ad esempio 13. *)?
pradip sutariya

13

Per ottenere Token Device puoi eseguire alcuni passaggi :

1) Abilita APNS (Apple Push Notification Service) sia per la certificazione dello sviluppatore che per la distribuzione della certificazione, quindi scarica nuovamente quei due file.

2) Scaricare di nuovo sia il file Developer Provisioning che quello Distribute Provisioning.

3) Nell'interfaccia Xcode: l'impostazione del provisioning per PROJECT e TARGETS con due file provisioning ha il download.

4) Infine, è necessario aggiungere il codice seguente nel file AppDelegate per ottenere Token Device (nota: eseguire l'app sul dispositivo reale).

- (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);
}

11

Usare descriptionquante più risposte suggeriscono è l' approccio sbagliato : anche se lo fai funzionare, si interromperà in iOS 13+.

Invece dovresti assicurarti di utilizzare i dati binari effettivi, non semplicemente una descrizione di essi. Andrey Gagan ha affrontato abbastanza bene la soluzione dell'Obiettivo C, ma fortunatamente è molto più semplice in rapida:

Swift 4.2 funziona su 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()

7

Obiettivo C per iOS 13+ , per gentile concessione della risposta di Wasif Saood

Copia e incolla il codice sottostante in AppDelegate.m per stampare il 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);
}

5

Il codice seguente viene utilizzato per recuperare il 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);

3
Questa non è mai stata la soluzione corretta. Non basare mai nulla su description.
rmaddy

5

E la versione Swift della risposta di Wasif:

Swift 2.x

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

Aggiornamento per Swift 3

let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()

Non usare mai descriptionsu dati binari (vedi qualsiasi altra risposta)
chris stamper

4

Se continui a non ricevere il token del dispositivo, prova a inserire il codice seguente in modo da registrare il dispositivo per la notifica push.

Funzionerà anche su ios8 o più.

#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

4

A partire da iOS 13 Apple ha cambiato [deviceToken description]output. Adesso è così{length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc} che non è corretto per il token del dispositivo.

Suggerisco di utilizzare questo frammento di codice per risolvere 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];
}

Funzionerà per iOS13 e versioni precedenti.


1
Cordiali saluti, qualsiasi risposta che sia mai descriptionstata utilizzata era sempre sbagliata. E questa è solo una possibile soluzione per convertire il token in una stringa. Una soluzione molto più semplice consiste nel convertire il file NSDatain una NSStringcodifica base64 standard.
rmaddy

1

Ottieni il token del dispositivo in Swift 3

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

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

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

}

1

Nella tua AppDelegate, nel didRegisterForRemoteNotificationsWithDeviceTokenmetodo:

Aggiornato per Swift:

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

0

Swift 4 Questo funziona per me:

Passaggio 1 in TARGET Fare clic su Aggiungi funzionalità e selezionare Notifiche push

Passaggio 2 in AppDelegate.swift aggiungi il codice seguente:

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)")
    }

-1

In un'impostazione di build impostare il profilo di fornitura della firma del codice se si dispone del certificato di abilitazione APN, si otterrà sicuramente l'ID del token. e rimuovi

Profilo di fornitura: automatico

e impostato su

Profilo di fornitura: il certificato del profilo di fornitura.


-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)")
}

-4

Per ottenere il token del dispositivo utilizzare il codice seguente, ma è possibile ottenere il token del dispositivo solo utilizzando il dispositivo fisico. Se hai l'obbligo di inviare il token del dispositivo, durante l'utilizzo del simulatore puoi inserire la condizione seguente.

  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"];
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.