Search code examples
iosapple-push-notificationsusernotifications

Is it correct to call registerForRemoteNotifications() all the time app starts?


From Apple Doc example on https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns

UIApplication.shared.registerForRemoteNotifications() is called all the time when app starts:

func application(_ application: UIApplication,
           didFinishLaunchingWithOptions launchOptions:
           [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
   // Override point for customization after application launch.

   UIApplication.shared.registerForRemoteNotifications()
   return true
}

Is it normal? Or we should use boolean preference and check if it's not registered and call it?

Also I need to request authorization from user to show notifications but in an appropriate place (e.g., in my Settings View Controller where I have a switch to enable/disable notifications)

  UNUserNotificationCenter.current().delegate = self
  let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
  UNUserNotificationCenter.current().requestAuthorization(
    options: authOptions,
    completionHandler: {_, _ in })

And it seems in this case I have to move all code from AppDelegate, e.g.: https://github.com/firebase/quickstart-ios/blob/master/messaging/MessagingExampleSwift/AppDelegate.swift to my Settings View Controller, even registerForRemoteNotifications().

So all delegates related to notifications (registering, receiving) will be in Settings View Controller. Is it going to work? Will I receive notifications in that place when App is not running?

Or where am I supposed to place different parts of the code?

Update

Also why they don't use

UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { settings in
    if settings.authorizationStatus == .notDetermined {
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
        options: authOptions) { granted, error in
            if granted {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    } else if settings.authorizationStatus == .denied {
        //
    } else if settings.authorizationStatus == .authorized {
        UIApplication.shared.registerForRemoteNotifications()
    }
})

instead of

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: {_, _ in })

UIApplication.shared.registerForRemoteNotifications()

?


Solution

  • I think the right approach is to call registerForRemoteNotifications() all the time app starts. Calling it only when user has authorized push notifications is dangerous. In fact, user, initially, could deny authorization, but then he could turn on notifications from device Settings app. In this case, app will not receive notifications until user reopens the app and this could be happen much later.