为什么不调用RegisterForRemoteNotificationsWithDeviceToken

我正在做一个应用程序,我想实施苹果推送通知服务。 我正在按照本教程中的步骤进行操作。

但是,仍然没有调用这些方法。 我不知道是什么原因造成的问题。 任何人都可以帮我吗?

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

我最终在苹果技术说明TN2265的帮助下解决了这个问题。

这就是我所做的:

首先,我仔细检查了我确实注册了推送通知 ,包括validation“aps-environment”密钥的供应configuration文件以及.app文件本身的密码设置。 我已经把它设置正确。

然后,我必须在控制台中debugging推送通知状态消息(您需要在设备上安装PersistentConnectionLogging.mobileconfig 预configurationconfiguration文件并重新启动它,请参阅“观察推送状态消息”下的TN2265 )。 我注意到,apns进程启动一个计时器并计算一个最小的启动date,这使我怀疑在这一点上通常出现的Push-Notification注册确认消息被APNS所抑制,如TN2265所示:

在iOS上重置推送通知权限警报

当推送应用程序第一次注册推送通知时,iOS会询问用户是否希望接收该应用程序的通知。 一旦用户对此警报作出响应,除非设备已恢复或应用程序已卸载至less一天,否则不会再次显示。

如果您想模拟首次运行您的应用,则可以将该应用卸载一天。 您可以实现后者,而无需等待一天,方法是将系统时钟设置为一天或更长时间,完全closures设备,然后重新打开设备。

所以,我从设备中删除了应用程序,然后在“设置”中手动更改了iPhone的date,重新启动了设备,然后重新安装了应用程序。

下一次我的代码调用registerForRemoteNotificationTypes ,它收到了预期的callback。

这为我解决了这个问题。 希望它有帮助。

在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

iOS 8中 ,除了以不同的方式请求推送通知访问外,还需要以不同方式注册。

申请进入:

 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]; 

并且configuration文件是APNS启用的。 启用APNS后,您可能需要重新下载configuration文件。 如果你有麻烦,你会得到错误,那么也许你应该创build一个Entitlements.plist,并根据构build的types添加值为“development”或“production”的关键字“aps-environment”(通常这个键值对是包含在configuration文件中,但有时Xcode与他们混淆)。

请记住,模拟器不支持远程通知。 因此,如果您在模拟器中运行您的应用程序,则不会调用didRegisterForRemoteNotificationsWithDeviceToken

如果之前使用configurationconfiguration文件来启用和configurationApple推送通知服务,则需要重新下载configurationconfiguration文件。

从Xcode Organizer和iPhone / iPad中删除configuration文件。 进入Settings -> General -> Profiles -> [Your provisioning] -> Remove

安装新下载的configuration文件。 然后清理并从XCode运行该项目。 现在应该调用didRegisterForRemoteNotificationsWithDeviceToken

我犯了一个错误,忽略了引导我到这里的实现细节。 我试图得到幻想,稍后在应用程序didRegisterForRemoteNotificationsWithDeviceToken过程中询问用户推送通知,所以我有我的registerForRemoteNotificationTypesdidRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithError所有在自定义UIView。

FIX: didRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithError需要在UIApplicationDelegateYourAppDelegate.m )中被触发。

现在看来很明显,嘿。

确保您的互联网连接已开启。 由于互联网连接,我花了几个小时才得到工作通知。

如果您已经添加了推送到现有的应用程序ID,请确保您重新生成您的供应configuration文件。 如果你不这样做,那么configuration文件将不会知道你启用了App ID。

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

获取设备令牌的最低要求:

无需configuration应用程序ID,供应或证书等,因此没有代码签名设置来获取委托方法didRegisterForRemoteNotificationsWithDeviceToken调用。

我刚刚在Xcode 7中为默认设置的单一视图创build了一个新的iOS项目,并给出了一个随机的bundle id,例如com.mycompany.pushtest,它在apple dev portal中没有configuration。

通过以下代码,我可以在我的iPad上通过互联网访问WIFI获取我的设备令牌,位于didRegisterForRemoteNotificationsWithDeviceToken方法中。 我的设备已连接,我只是直接从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); } 

试试这个为我工作,

第一步

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

第二步

添加以下代码function

  #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 

您将在下面的function中获得设备令牌

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

详细的回答请参考这个

希望这是对某个人的帮助。

这发生在我身上,因为我重置并删除了手机上的所有数据(想要开发手机使用)。 这样在再次设置电话之后,就完全阻止了APN的连接。

我尝试了各种各样的东西,但是唯一解决这个问题的就是将手机设置为与新SIM卡下的运营商合作。

这个链接提供了更多关于可能发生的事情的提示: https : //developer.apple.com/library/ios/technotes/tn2265/_index.html

它说,APN试图优先通过运营商/塔而不是无线连接。 也许这个问题也是在wifinetworking上的路由器阻塞端口5223上发生的,但是我怀疑它是因为在全局复位发生之前的前一天它工作正常。

我对此有一个观点。最近我也面临这个问题。我根据文档做了所有事情,但委托方法并没有调用。最后,我看到一个职位说networking的问题,然后我改变了networking,它工作正常。所以,关心networking也是因为很less的networking可以阻止APNS。

对我来说,解决了这个问题就是在构build设置和代码签名部分,手动select代码签名标识和configuration文件。 很明显,自动设置并不是正确的,因此应用程序没有得到正确的授权。

如果closures应用程序的推送消息,

appdidRegisterForRemoteNotificationsWithDeviceToken永远不会被调用

另外,请不要忘记在Apple https://developer.apple.com/system-status/上检查系统状态。;

我尝试了上述所有的解决scheme,但最终的错误是因为APNS服务停机! 第二天,所有人都按预期再次工作。

另外,你的callback方法有一个错字:

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

Rupesh指出正确的方法名称是:

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

这可能就是为什么你从来没有收到你的情况令牌!

您需要从didFinishLaunchingWithOptions中调用registerForNotifications方法。

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

我遇到了一个不同的问题,那就是我的推送通知callback被第三方库(包括Firebase)劫持了。 这些库swizzle推送通知callback方法来获取callback。

希望这有助于某人。