iOS 9 では、
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeoutDate];
didRegisterForRemoteNotificationsWithDeviceTokenリッスンもデリゲートも行いませんが、他のデリゲートdidFailToRegisterForRemoteNotificationsWithErrorをリッスンします。iOS 7 と iOS 8 では問題なく動作していました。applicationDidEnterBackgroundUIApplication
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
dispatch_async(dispatch_get_main_queue(), ^{
[self waitForCompletion:30];
});
return YES;
}
- (bool)waitForCompletion:(NSTimeInterval)timeoutSecs {
NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeoutSecs];
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeoutDate];
if ([timeoutDate timeIntervalSinceNow] < 0.0)
break;
} while (!_done);
return _done;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
// send device token to server
_done = true;
}
application:didRegisterForRemoteNotificationsWithDeviceToken常に 30 秒後に呼び出します (タイムアウト値)。