Подтвердить что ты не робот

Почему didRegisterForRemoteNotificationsWithDeviceToken не вызывается

Я делаю приложение, в котором я хочу реализовать службу push push-уведомлений. Я следую пошаговым инструкциям, приведенным в этом учебнике.

Но все же методы не вызываются. Я не знаю, что вызывает проблему. Кто-нибудь может мне помочь?

    - (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
        //NSString * token = [[NSString alloc] initWithData:deviceTokenencoding:NSUTF8StringEncoding];
        NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
        NSLog(@"Device Token:%@",str);

        //NSLog(@"Device token is called");
        //const void *devTokenBytes = [deviceToken bytes];
        //NSLog(@"Device Token");
    }

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

Ответ 1

У меня была такая же проблема: вызов registerForRemoteNotificationTypes: не вызывал ни application:didRegisterForRemoteNotificationsWithDeviceToken:, ни application:didFailToRegisterForRemoteNotificationsWithError:

В конце концов я решил эту проблему с помощью технической заметки Apple TN2265.

Это то, что я сделал:

Во-первых, я дважды проверил, что я действительно правильно регистрируется для Push-уведомлений, включая проверку моего профиля подготовки для "aps-environment" ключ и кодовое обозначение самого файла .app. Я все правильно настроил.

Затем мне пришлось отлаживать сообщения о статусе Push Notification в консоли (вам необходимо установить профиль ProvistentConnectionLogging.mobileconfig на вашем устройстве и перезагрузить его. См. TN2265 в разделе "Наблюдение за сообщениями о статусе Push Push" ). Я заметил, что процесс apns запускает таймер и вычисляет минимальную дату пожара, что заставило меня подозревать, что сообщение подтверждения регистрации Push-Notification, которое обычно представляется на этом этапе, подавляется APNS, как указано в TN2265:

Сброс уведомлений о предупреждениях Push Push для iOS

При первом включении приложений с поддержкой push-push для push-уведомлений iOS запрашивает у пользователя, хотят ли они получать уведомления для этого приложения. Как только пользователь ответил на это предупреждение, он не будет представлен повторно, если устройство не будет восстановлено или приложение не будет удалено, по крайней мере, на один день.

Если вы хотите имитировать первый запуск вашего приложения, вы можете оставить приложение удаленным в течение дня. Вы можете добиться последнего, не дожидаясь дня, установив системные часы вперед на день или более, полностью выключив устройство, а затем снова включив устройство.

Итак, я удалил приложение с устройства, а затем вручную изменил дату iPhone в настройках, перезагрузил устройство и снова установил приложение.

В следующий раз, когда мой код под названием registerForRemoteNotificationTypes, он получил обратные вызовы, как ожидалось.

Это решило проблему для меня. Надеюсь, поможет.

Ответ 2

В iOS 8 некоторые методы устарели. Выполните следующие действия для совместимости с iOS 8

1. Зарегистрировать уведомление

if([[UIDevice currentDevice] systemVersion].floatValue >= 8.0)
{
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];    
}
else
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
}

2. Добавить 2 метода

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

//For interactive notification only
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}

Примечание: в дополнение к didRegisterForRemoteNotificationsWithDeviceToken и didReceiveRemoteNotification требуется еще два новых метода в iOS 8. В противном случае метод делегирования не будет вызываться.

Смотрите: Удаленное уведомление iOS 8

Ответ 3

В iOS 8, помимо запроса доступа push-уведомлений по-разному, вам также необходимо зарегистрировать по-разному.

Доступ к запросу:

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // iOS 8
    UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
    // iOS 7 or iOS 6
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}

Обработайте зарегистрированное устройство:

// New in iOS 8
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

// iOS 7 or iOS 6
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    // Send token to server
}

Ответ 4

Убедитесь, что вы звоните в свой код (обновление в соответствии с поддерживаемыми видами уведомлений)

[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

а профиль обеспечения - включен APNS. Возможно, вам придется повторно загрузить профиль обеспечения после внедрения APNS. Если у вас есть проблемы и вы получаете ошибки, то, возможно, вам следует создать Entitlements.plist и добавить ключ "aps-environment" со значением "development" или "production" в зависимости от типа сборки (обычно эта пара ключ-значение содержащиеся в профиле обеспечения, но иногда Xcode беспорядок с ними). ​​

Ответ 5

Помните, что удаленные уведомления не поддерживаются в симуляторе. Поэтому, если вы запустите приложение в симуляторе, didRegisterForRemoteNotificationsWithDeviceToken не будет вызываться.

Ответ 6

Если профили подготовки используются до включения и настройки службы уведомления Apple Push, вам необходимо снова загрузить профили подготовки.

Удалить профили настройки из Xcode Organizer и с iPhone/iPad. Перейдите к Settings -> General -> Profiles -> [Your provisioning] -> Remove.

Установите новые загруженные профили подготовки. Затем очистите и запустите проект из XCode. Теперь следует вызвать didRegisterForRemoteNotificationsWithDeviceToken.

Ответ 7

Я допустил ошибку и упустил из виду детали реализации, которые привели меня сюда. Я попытался получить фантазию и попросить пользователя Push Notifications позже в процессе работы с приложением, поэтому у меня были все registerForRemoteNotificationTypes, didRegisterForRemoteNotificationsWithDeviceToken и didFailToRegisterForRemoteNotificationsWithError все в пользовательском UIView.

ИСПРАВЛЕНИЕ: didRegisterForRemoteNotificationsWithDeviceToken и didFailToRegisterForRemoteNotificationsWithError должны быть в UIApplicationDelegate (YourAppDelegate.m) для запуска.

теперь кажется очевидным, хех.

Ответ 8

Убедитесь, что подключение к Интернету включено. Мне потребовались часы, чтобы получать уведомления о работе из-за подключения к Интернету.

Ответ 9

Если вы добавили push к существующему идентификатору приложения, убедитесь, что вы повторно создаете профили обеспечения. Если вы этого не сделаете, профиль не будет знать о том, как включить идентификатор приложения.

Ответ 10

Попробуйте, чтобы он работал у меня,

Первый шаг

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

В приведенном выше методе добавьте ниже код

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

Второй шаг

Добавьте ниже код Функция

 #ifdef __IPHONE_8_0
   - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
   {
  //register to receive notifications
  [application registerForRemoteNotifications];
  }

 - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
  {
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
   else if ([identifier isEqualToString:@"answerAction"]){
   }
}
 #endif

Вы получите токен устройства ниже функции

 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 

для подробного ответа, пожалуйста, обратитесь This

Надеюсь, что это поможет кому-то.

Ответ 11

-​(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. ​​​​[window​addSubview:viewController.view]; ​​​​[window​makeKeyAndVisible];
NSLog(@"Registering for push notifications...");
 [[UIApplication sharedApplication]
registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)]; 
​​​​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);
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
for (id key in userInfo) { NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
}

Ответ 12

Минимальное требование для получения маркера устройства:

Не нужно настраивать идентификатор, инициализацию или сертификат приложения, поэтому нет необходимости подписывать код, чтобы получить делегат метод сделалRegisterForRemoteNotificationsWithDeviceToken.

Я только что создал новый проект iOS в Xcode 7 для одного представления с настройками по умолчанию и дал случайный идентификатор пакета, такой как com.mycompany.pushtest, который не настроен в портале apple dev.

С помощью следующего кода я получаю токен своего устройства в методе didRegisterForRemoteNotificationsWithDeviceToken на своем iPad с доступом в Интернет к WIFI. Мое устройство подключено, и я просто запускаю приложение непосредственно из xcode и просматривая значения в консоли xcode.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions   

{  
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])  
    {  
        UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);  
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];  
        [application registerUserNotificationSettings:settings];  
        [application registerForRemoteNotifications];  
    }  
    else  
    {  
        // Register for Push Notifications, if running iOS version < 8  
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];  
    }  
    return YES;  
}  


- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Error: %@", error.description);
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken);
}

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    NSLog(@"NotificationSettings: %@", notificationSettings);
}

Ответ 13

У меня есть точка в этом. Недавно я тоже сталкиваюсь с этой проблемой. Я сделал все в соответствии с документацией, но метод делегирования не вызывал. Наконец, я увидел один пост говорит, что проблема с сетью. Затем я изменил сеть и он отлично работает. Поэтому заботиться о сети также потому, что несколько сетей могут блокировать APNS.

Ответ 14

если вы отключите push-сообщение приложения,

appdidRegisterForRemoteNotificationsWithDeviceToken никогда не будет называться

Ответ 15

Это случилось со мной, потому что я reset и удалил все данные на телефоне (хотел использовать dev-телефон). Это предотвратило подключение APN после настройки телефона еще раз.

Я пробовал всевозможные вещи, но единственное, что это исправляло, заключалось в том, чтобы настроить телефон на работу с перевозчиком под новой SIM-картой.

Эта ссылка предлагает больше подсказок относительно того, что могло бы произойти: https://developer.apple.com/library/ios/technotes/tn2265/_index.html

В нем говорится, что APN пытается подключиться преимущественно через несущую/башню, а не Wi-Fi. Возможно, проблема также заключалась в том, что что-то происходит с портом 5223 блокировки маршрутизатора в сети Wi-Fi, но я сомневаюсь, потому что он работал нормально в предыдущий день до того, как произошел глобальный reset.

Ответ 16

Для меня это решило, что оно собиралось в настройках сборки и в разделе подписи кода, вручную выбрав идентификатор подписи кода и профиль подготовки. По-видимому, автоматическая настройка не была выбрана правильно, поэтому приложение не было должным образом разрешено.

Ответ 17

Кроме того, не забудьте проверить состояние системы в Apple https://developer.apple.com/system-status/.

Я пробовал все вышеперечисленные решения, но в конце концов ошибка была в том, что служба APNS была отключена! На следующий день все снова работало, как ожидалось.

Кроме того, у вас есть опечатка в методе обратного вызова:

- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

Как указал Рупеш, правильное имя метода:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

Вероятно, поэтому вы никогда не получали токен в своем случае!

Ответ 18

Вам нужно вызвать метод registerForNotifications из файла didFinishLaunchingWithOptions.

 func registerForNotifications(){

        if #available(iOS 10.0, *) {

            let center = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options:[.alert,.sound,.badge]) { (granted, error) in
                if granted{
                    UIApplication.shared.registerForRemoteNotifications()
                }else{

                    print("Notification permission denied.")

                }
            }

        } else {

            // For iOS 9 and Below
            let type: UIUserNotificationType = [.alert,.sound,.badge];
            let setting = UIUserNotificationSettings(types: type, categories: nil);
            UIApplication.shared.registerUserNotificationSettings(setting);
            UIApplication.shared.registerForRemoteNotifications()
        }
    }

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

        let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
        print(token)

    }


extension AppDelegate : UNUserNotificationCenterDelegate{

    @available(iOS 10.0, *)

    func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {
        print("Handle push from foreground")

        let info = ((notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
        if let type = info.value(forKey: "type") as? Int{
            if type == 0 {  

         // notification received ,Handle your notification here

            }
        }
    }

    @available(iOS 10.0, *)

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        print("Handle push from background or closed")

        let info = ((response.notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
        if let type = info.value(forKey: "type") as? Int{
            if type == 0 {   

            // notification received ,Handle your notification here
            }
        }
    }
}

Ответ 19

У меня была другая проблема, в которой мои обратные вызовы push-уведомлений были захвачены сторонними библиотеками, которые я включил, а именно Firebase. Эти библиотеки подталкивают методы обратного вызова уведомлений для получения обратных вызовов.

Надеюсь, это поможет кому-то.

Ответ 20

После того, как вы потратили самое опасное 3h, выполните следующие действия:

  1. Удаление приложения

  2. Сбросить устройство

  3. Запустить снова

Это просто сработало