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

Я делаю приложение, в котором я хочу реализовать службу уведомления Apple 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); } 

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

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

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

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

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

    Сброс предупреждений о разрешении Push-уведомлений на iOS

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

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

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

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

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

    В 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"]){ } } 

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

    См. Удаленное уведомление iOS 8

    В 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 } 

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

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

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

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

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

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

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

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

    didRegisterForRemoteNotificationsWithDeviceToken : didRegisterForRemoteNotificationsWithDeviceToken и didFailToRegisterForRemoteNotificationsWithError должны быть в UIApplicationDelegate ( YourAppDelegate.m ) для YourAppDelegate.m .

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

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

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

    Попытайтесь, чтобы это работало для меня,

    Первый шаг

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

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

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

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

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

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

    Я только что создал новый проект 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); } 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Вам нужно вызвать метод 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 } } } } 

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

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

    Давайте будем гением компьютера.