How to control when to prompt user for push notification permissions in iOS

I’ve built an application for iPhone using Swift and Xcode 6, and the Parse framework to handle services.

While following the Parse tutorials on how to set up push notifications, the instructions advised that I put the push notifications in the App Delegate file.

  • iOS Swift: Calling a singleton method 3 times causes app to crash
  • Error compiling storyboard files using Xcode 6 beta 5
  • Google Maps SDK for iOS doesn't display map content
  • How to keep downloading new images in background even if user force quits the app in iOS objective C?
  • scale fit mobile web content using viewport meta tag
  • dyld: Library not loaded: @rpath/SwiftyJSON.framework/SwiftyJSON
  • This is the code that I have added to the App Delegate file…

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
        var pushNotificationsController: PushNotificationController?
    
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
             // Register for Push Notifications
            self.pushNotificationsController = PushNotificationController()
    
            if application.respondsToSelector("registerUserNotificationSettings:") {
                println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
                let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
                let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
                application.registerUserNotificationSettings(settings)
                application.registerForRemoteNotifications()
            }
    
            return true;
        }
    
        func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
            println("didRegisterForRemoteNotificationsWithDeviceToken")
            let installation = PFInstallation.currentInstallation()
            installation.setDeviceTokenFromData(deviceToken)
            installation.saveInBackground()
        }
    }
    

    So what happens is that as soon as the application is launched for the first time, the user is prompted to grant these permissions.

    What I want to do, is only prompt for these permissions after a certain action has taken place (ie, during a walkthrough of the features of the app) so I can provide a little more context on why we would want them to allow push notifications.

    Is it as simple as just copying the below code in the relevant ViewController where I will be expecting to prompt the user?

    // In 'MainViewController.swift' file
    
    func promptUserToRegisterPushNotifications() {
            // Register for Push Notifications
            self.pushNotificationsController = PushNotificationController()
    
            if application.respondsToSelector("registerUserNotificationSettings:") {
                println("registerUserNotificationSettings.RegisterForRemoteNotificatios")
                let userNotificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
                let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
                application.registerUserNotificationSettings(settings)
                application.registerForRemoteNotifications()
            }
    }
    
    func application(application: UIApplication,    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
            println("didRegisterForRemoteNotificationsWithDeviceToken")
            let installation = PFInstallation.currentInstallation()
            installation.setDeviceTokenFromData(deviceToken)
            installation.saveInBackground()
    }
    

    thanks!

    3 Solutions Collect From Internet About “How to control when to prompt user for push notification permissions in iOS”

    The answer is simple. If you want the user to be prompted some other time, for instance on a button press then simply move the code regarding the request into that function (or call promptUserToRegisterPushNotifications() from somewhere else).

    Hope that helps 🙂

    This is for Swift 2. I have placed promptUserToRegisterPushNotifications() in MainViewController.swift, but I have left didRegisterForRemoteNotificationsWithDeviceToken in AppDelegate because it didn’t work when I place it on the same MainViewController.swift.

    // In 'MainViewController.swift' file
    func promptUserToRegisterPushNotifications() {
        // Register for Push Notifications
    
        let application: UIApplication = UIApplication.sharedApplication()
    
        if application.respondsToSelector(#selector(UIApplication.registerUserNotificationSettings(_:))) {
            print("registerUserNotificationSettings.RegisterForRemoteNotificatios")
    
            let notificationSettings = UIUserNotificationSettings(
                forTypes: [.Badge, .Sound, .Alert], categories: nil)
            application.registerUserNotificationSettings(notificationSettings) // Register for Remote Push Notifications
            application.registerForRemoteNotifications()
        }
    }
    
    
    // In AppDelegate
    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
        var tokenString = ""
    
        for i in 0..<deviceToken.length {
            tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
        }
    
        NSUserDefaults.standardUserDefaults().setObject(tokenString, forKey: "deviceToken")
    
        print("Device Token:", tokenString)
    
    }
    

    This is method I have written in the code and works fine once it called on launch (didFinishLaunch)

    class func registerNotification() {
        if #available(iOS 10.0, *) {
            // push notifications
            UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge]) {
                (granted, error) in
                if (granted) {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
    
            let center  = UNUserNotificationCenter.current()
            center.delegate = AppManager.appDel()
            center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
                if error == nil {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        } else {
            UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
            UIApplication.shared.registerForRemoteNotifications()
        }
    }