iOS 10 - didRegisterForRemoteNotificationsWithDevicetoken 仅在第一次调用

Posted

技术标签:

【中文标题】iOS 10 - didRegisterForRemoteNotificationsWithDevicetoken 仅在第一次调用【英文标题】:iOS 10 - didRegisterForRemoteNotificationsWithDevice only called the first time 【发布时间】:2016-11-01 11:38:17 【问题描述】:

我遇到了一个问题,在 ios 10 上,我在重新安装应用程序后第一次调用 registerForRemoteNotifications 时才调用 didRegisterForRemoteNotificationsWithDevice。

发生了什么:卸载应用程序,然后从 XCode 调试运行应用程序后,我在应用程序内弹出窗口上点击“允许”,我确实收到了“使用设备令牌注册远程通知!”的日志消息! ,我得到一个设备令牌。这让我犹豫不决地认为我的证书/配置文件没问题。但是,此设备令牌似乎不适用于发送推送通知(可能是服务器上的单独问题),并且在关闭应用程序并重新打开它后,我只看到“推送授权已授予:1”和“推送注册开始。”但没有允许推送通知的弹出窗口,也没有 didRegister 回调/令牌。

我尝试寻找解决方案,但我找不到任何人第一次显示 didRegister 函数,所以我不确定是什么原因造成的。

这是应用程序正在使用的代码:

-(void)registerForNotifications

#if !TARGET_IPHONE_SIMULATOR
if(SYSTEM_VERSION_LESS_THAN(@"10.0")) 
    // This part is irrelevant, doesn't get called on iOS 10
    -> some code for push notifications

else 
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
     
         NSLog(@"push authorization granted: %d", granted);
         if(!error)
         
             [[UIApplication sharedApplication] registerForRemoteNotifications];
             NSLog(@"Push registration starting.");
         
         else
         
             NSLog(@"Push registration FAILED");
             NSLog(@"ERROR: %@ - %@", error.localizedFailureReason, error.localizedDescription);
             NSLog(@"SUGGESTIONS: %@ - %@", error.localizedRecoveryOptions, error.localizedRecoverySuggestion);
           
     ];

#endif


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

    NSLog(@"did register for remote notifications with device!");
    [self handleNewDeviceToken:deviceToken];

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

    NSLog(@"did register for remote notifications with device token!");
    [self handleNewDeviceToken:deviceToken];

我希望这对我来说只是一些愚蠢的事情/对于配置文件或证书,我对 iOS 开发还没有太多经验。如果您可以使用任何其他信息,请告诉我。

编辑 好吧,根本问题是我的代码在每次调用 register 之前都调用了 unregisterForRemoteNotifications。显然,iOS10 发生了变化,调用 unregister 会导致 register 在一段时间后无法工作。

【问题讨论】:

【参考方案1】:

这看起来是一个 iOS 10 错误,更多开发人员抱怨在这里遇到类似问题:https://forums.developer.apple.com/thread/63038。

据我所知,在您调用unregisterForRemoteNotifications 之后,随后尝试调用registerForRemoteNotifications不会调用任何:

didRegisterForRemoteNotificationsWithDeviceToken 也不是didFailToRegisterForRemoteNotificationsWithError

AppDelegate 上的方法。基本上你不会收到来自 iOS 的任何回调。

我目前知道的唯一解决方法是向 Info.plist 添加 background fetch 功能。我可以确认这解决了我的问题,但您需要评估该解决方案是否对您合理。

【讨论】:

啊,太棒了!感谢您的回答。不幸的是,我的工作日快结束了,所以我无法尝试你的修复,但我明天会更新这个:) 好吧,虽然您建议的解决方案对我没有多大帮助,但我确实注意到您链接的主题中提到的其他内容 - “问题似乎是 iOS 10 阻止注册推送通知注销后一段时间(24 小时?)与 Apple 合作”。显然我的应用程序在重新注册之前每次都调用取消注册。非常感谢您的链接!【参考方案2】:

对我来说,唯一可行的解决方案是并行使用旧式注册:

center.requestAuthorization(options: [.badge, .alert , .sound])  (granted, error) in ... 

let notificationSettings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)

【讨论】:

以上是关于iOS 10 - didRegisterForRemoteNotificationsWithDevicetoken 仅在第一次调用的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发 适配iOS10

iOS开发 如何适配iOS10

iOS - 如何适配iOS10(插曲)

iOS 8、iOS 9、iOS 10 和 iOS 11 上的 UITabBar 的高度是多少?

iOS:Xcode8以下真机测试iOS10.0和iOS10.1配置包

iOS10适配相关