问题
I'm having a problem where didRegisterForRemoteNotificationsWithDevice only gets called the first time I call registerForRemoteNotifications after reinstalling the app, on iOS 10.
What's happening: after uninstalling the app and then running the app in debug from XCode, I tap "allow" on the in-app popup and I do get my log message for "did register for remote notifications with device token!", and I get a device token. This makes me hesitantly think that my certificate / provisioning profiles are OK. However, this device token doesn't seem to work for sending push notifications (might be a separate issue on the server), and after closing the app and reopening it, I only see "Push authorization granted: 1" and "Push registration starting." but no popup to allow push notifications, and no didRegister callback/token.
I tried finding solutions, but I couldn't find anyone for whom the didRegister function only shows the first time so I'm not sure what could be causing it.
This is the code that the app is using:
-(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];
}
I'm hoping this is just something stupid on my side / with provisioning profiles or certificates, I'm not too experienced with iOS development yet. Do let me know if you could use any additional information.
EDIT Alright, the underlying issue was that my code was calling unregisterForRemoteNotifications every time before calling register. Apparently, iOS10 had a change where calling unregister causes register not to work for a bunch of time after.
回答1:
This looks lie an iOS 10 bug and couple of more developers are complaining to experience similar issue here: https://forums.developer.apple.com/thread/63038.
From what I see, the subsequent attempts to call registerForRemoteNotifications after you have called unregisterForRemoteNotifications will not invoke any of:
didRegisterForRemoteNotificationsWithDeviceToken- nor
didFailToRegisterForRemoteNotificationsWithError
methods on AppDelegate. Basically you don't receive any callback from the iOS.
The only workaround that I am currently aware of, is to add background fetch capability to you Info.plist. I can confirm that this solved the issue for me, but you would need to evaluate whether that solution os plausible for you.
回答2:
For me the only working solution was to use the old-style-registration in parallel:
center.requestAuthorization(options: [.badge, .alert , .sound]) { (granted, error) in ... }
let notificationSettings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
来源:https://stackoverflow.com/questions/40359310/ios-10-didregisterforremotenotificationswithdevice-only-called-the-first-time