Отримайте маркер пристрою для push-сповіщення


84

Я працюю над push-сповіщеннями. Я написав наступний код для отримання маркера пристрою.

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

Я можу успішно запустити додаток на пристрої, але не можу отримати ідентифікатор пристрою на консолі.

У мене немає проблем із профілями сертифікації та забезпечення.


Ви виконали всі кроки ? Якщо у вас не виникає проблем із сертифікацією та наданням, а також з кодом, ви, мабуть, робите невелику помилку. Подобається..скажіть, ви запускаєте додаток на реальному пристрої, приєднуючи його до вашої системи? Також ви не помічаєте, отримуєте ви маркер пристрою в журналі консолі чи ні? Ви ввімкнули push-сповіщення в iPhone ?
Сара

Я не можу отримати маркер пристрою в журналі консолі.
jagzzz

Я запускаю програму на реальному пристрої без помилок.
jagzzz

Ви ввімкнули APNS, як показано в посиланні на iPhone?
Сара

так, я ввімкнув APNS .. але маркер пристрою не може отримати на cosole
jagzzz

Відповіді:


162

ПРИМІТКА. Наведене нижче рішення більше не працює на пристроях iOS 13+ - воно поверне дані про сміття .

Будь ласка, використовуйте наступний код:

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

Рішення, яке працювало до iOS 13:

Завдання-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);
} 

Свіфт 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
Тоді перевірте свій профіль підготовки, він повинен мати ідентифікатор програми, за допомогою якого ви створили свій ssl сертифікат для push-сповіщення.
Wasif Saood

1
вам потрібно додати код у файл AppDelegate @jagzzz
codercat

2
Для тих, кого цікавить приклад коду, написаний у Swift: gist.github.com/sawapi/a7cee65e4ad95578044d
Бенджамін

3
Обережно, використовуючи «опис» властивість більше не працює: stackoverflow.com/questions/39495391 / ...
hariseldon78

1
@codester Я завантажив свою збірку за допомогою Xcode 10.3, і вона працює. Відповідно до вашого твердження, метод Objective C буде зламаний в подальшому XCode 11, але те, що я бачу в нашій базі даних, - це показ довжини даних замість правильного рядка маркера apns. Тож я просто хочу знати, що це залежить від версії Xcode або версії iOS (тобто 13. *)?
pradip sutariya

13

Щоб отримати Пристрій Token, Ви можете зробити кілька кроків :

1) Увімкніть APNS (Служба сповіщень Apple Push) як для сертифікації розробника, так і для розподіленої сертифікації, а потім перезавантажте ці два файли.

2) Перезавантажте як файл розробника, так і розподілене забезпечення.

3) В інтерфейсі Xcode: встановлення забезпечення для PROJECT та TARGETS з двома файлами для забезпечення завантаження.

4) Нарешті, вам потрібно додати код нижче у файл AppDelegate, щоб отримати Token Device (примітка: запустити додаток на реальному пристрої).

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

Використання descriptionстількох цих відповідей свідчить про неправильний підхід - навіть якщо ви змусите його працювати, він вийде з ладу в iOS 13+.

Натомість вам слід забезпечити використання фактичних двійкових даних, а не просто їх опис. Андрій Гаган досить добре звернувся до рішення Objective C, але на щастя це набагато простіше швидко:

Swift 4.2 працює в 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

Завдання C для iOS 13+ , люб’язно надано відповідь Wasif Saood

Скопіюйте та вставте код нижче в AppDelegate.m, щоб надрукувати маркер APN пристрою.

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

Наступний код використовується для отримання маркера пристрою.

    // 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
Це ніколи не було правильним рішенням. Ніколи не базуйте нічого на description.
rmaddy

5

І швидка версія відповіді Wasif:

Свіфт 2.x

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

Оновлення для Swift 3

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

Ніколи не використовуйте descriptionдля двійкових даних (див. Будь-яку іншу відповідь)
cdstamper

4

Якщо ви все ще не отримуєте маркер пристрою, спробуйте вказати наступний код, щоб зареєструвати пристрій для push-сповіщення.

Він також буде працювати на ios8 або більше.

#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

3

Починаючи з iOS 13, Apple змінила [deviceToken description]випуск. Тепер це як {length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc}неправильно для маркера пристрою.

Я пропоную використовувати цей фрагмент коду для вирішення проблеми:

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

Це буде працювати для iOS13 і старіших версій.


1
FYI - будь-яка відповідь, яка коли-небудь використовувалася, descriptionзавжди була неправильною. І це лише одне можливе рішення для перетворення маркера в рядок. Набагато простіше рішення перетворити NSDataдо NSStringвикористовуючи стандартну кодування base64.
rmaddy

1

Отримайте маркер пристрою в Swift 3

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

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

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

}

1

У вашому AppDelegate, у didRegisterForRemoteNotificationsWithDeviceTokenметоді:

Оновлено для Swift:

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

0

Свіфт 4 Це мені підходить:

Крок 1 у ЦІЛІ Клацніть на Додати можливість та виберіть Push-сповіщення

Крок 2 в AppDelegate.swift додайте такий код:

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

У налаштуваннях збірки встановіть профіль підписання коду, якщо у вас є сертифікат увімкнення APN, тоді ви точно отримаєте ідентифікатор маркера. і видалити

Профіль забезпечення: автоматичний

і встановити на

Профіль забезпечення: Ваш сертифікат профілю забезпечення.


-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

Для того, щоб отримати маркер пристрою, використовуйте наступний код, але ви можете отримати маркер пристрою лише за допомогою фізичного пристрою. Якщо ви зобов’язані надсилати маркер пристрою, тоді під час використання симулятора ви можете поставити нижченаведену умову.

  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"];
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.