diff --git a/Riot/AppDelegate.h b/Riot/AppDelegate.h index 863f96b08..dd33b3579 100644 --- a/Riot/AppDelegate.h +++ b/Riot/AppDelegate.h @@ -116,6 +116,13 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification; - (void)registerUserNotificationSettings; +/** + Perform registration for remote notifications. + + @param completion the block to be executed when registration finished. + */ +- (void)registerForRemoteNotificationsWithCompletion:(void (^)(NSError *))completion; + #pragma mark - Matrix Room handling - (void)showRoom:(NSString*)roomId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession; diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 37989a831..b4647fa28 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -168,6 +168,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN @property (strong, nonatomic) UIAlertController *mxInAppNotification; @property (strong, nonatomic) UIAlertController *incomingCallNotification; +@property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *); + @end @implementation AppDelegate @@ -897,12 +899,24 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN } } +- (void)registerForRemoteNotificationsWithCompletion:(nullable void (^)(NSError *))completion +{ + self.registrationForRemoteNotificationsCompletion = completion; + [[UIApplication sharedApplication] registerForRemoteNotifications]; +} + - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { // Register for remote notifications only if user provide access to notification feature if (notificationSettings.types != UIUserNotificationTypeNone) { - [application registerForRemoteNotifications]; + [self registerForRemoteNotificationsWithCompletion:nil]; + } + else + { + // Clear existing token + MXKAccountManager* accountManager = [MXKAccountManager sharedManager]; + [accountManager setApnsDeviceToken:nil]; } } @@ -915,11 +929,23 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN [accountManager setApnsDeviceToken:deviceToken]; isAPNSRegistered = YES; + + if (self.registrationForRemoteNotificationsCompletion) + { + self.registrationForRemoteNotificationsCompletion(nil); + self.registrationForRemoteNotificationsCompletion = nil; + } } - (void)application:(UIApplication*)app didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { NSLog(@"[AppDelegate] Failed to register for APNS: %@", error); + + if (self.registrationForRemoteNotificationsCompletion) + { + self.registrationForRemoteNotificationsCompletion(error); + self.registrationForRemoteNotificationsCompletion = nil; + } } - (void)cancelBackgroundSync diff --git a/Riot/ViewController/SettingsViewController.m b/Riot/ViewController/SettingsViewController.m index dfc8ad67d..b37d1e6e0 100644 --- a/Riot/ViewController/SettingsViewController.m +++ b/Riot/ViewController/SettingsViewController.m @@ -2562,7 +2562,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); - (void)togglePushNotifications:(id)sender { // Check first whether the user allow notification from device settings - if ([[MXKAccountManager sharedManager] isAPNSAvailable] == NO) + UIUserNotificationType currentUserNotificationTypes = UIApplication.sharedApplication.currentUserNotificationSettings.types; + if (currentUserNotificationTypes == UIUserNotificationTypeNone) { [currentAlert dismissViewControllerAnimated:NO completion:nil]; @@ -2594,10 +2595,28 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); { [self startActivityIndicator]; - MXKAccount* account = [MXKAccountManager sharedManager].activeAccounts.firstObject; + MXKAccountManager *accountManager = [MXKAccountManager sharedManager]; + MXKAccount* account = accountManager.activeAccounts.firstObject; - // toggle the pushes - [account setEnablePushNotifications:!account.pushNotificationServiceIsActive]; + if (accountManager.apnsDeviceToken) + { + [account setEnablePushNotifications:!account.pushNotificationServiceIsActive]; + } + else + { + // Obtain device token when user has just enabled access to notifications from system settings + [[AppDelegate theDelegate] registerForRemoteNotificationsWithCompletion:^(NSError * error) { + if (error) + { + [(UISwitch *)sender setOn:NO animated:YES]; + [self stopActivityIndicator]; + } + else + { + [account setEnablePushNotifications:YES]; + } + }]; + } } }