Register for remote notifications outside of app delegate

12,573

Solution 1

You can do the registration call at any time - and it is a good idea to only do so when you know in the app you would like the user to receive push notifications.

The two application delegate callbacks have to be in your app delegate though, as you register for notification types on the application delegate and you only have one. I would suggest making an application delegate method to call that then does the registration, you could call it from your view controller through [[UIApplication sharedApplication] delegate] (cast the result of that call to your application delegate class).

Solution 2

this answer is to 'vote up' reply from Kendall Helmstetter Gelner (Kendall's answer has 0 vote ups, but it worked great for me, and i do not have enough points to vote up the answer). following Kendall's advice, my view controller, CMRootViewController.m ->

#pragma mark - push notificaiton
-(void)registerToReceivePushNotification {
    // Register for push notifications
    UIApplication* application =[UIApplication sharedApplication];
    [application registerForRemoteNotificationTypes:
     UIRemoteNotificationTypeBadge |
     UIRemoteNotificationTypeAlert |
     UIRemoteNotificationTypeSound];
}

and the two application delegate callbacks are in my app delegate, CMAppDelegate.m ->

// handle user accepted push notification, update parse
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)newDeviceToken {
    // Store the deviceToken in the current installation and save it to Parse.
    PFInstallation *currentInstallation = [PFInstallation currentInstallation];
    [currentInstallation setDeviceTokenFromData:newDeviceToken];

    // enable future push to deviceId
    NSUUID *identifierForVendor = [[UIDevice currentDevice] identifierForVendor];
    NSString* deviceId = [identifierForVendor UUIDString];
    [currentInstallation setObject:deviceId forKey:@"deviceId"];

    [currentInstallation saveInBackground];
}


// handle push notification arrives when app is open
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
    [PFPush handlePush:userInfo];
}

thank you Kendall.

Solution 3

The best method is to, in your app delegate method to handle the remove notification, send out a notification using NSNotificationCenter

[[NSNotificationCenter defaultCenter] postNotification:@"remoteNotification" withObject:whateverYouWantHere];

Then use the NSNotificationCenter to add any interested UIViewControllers as an observer for the remoteNotification notification.

Solution 4

SWIFT 3 and Above

To Call Push Notification from outside of AppDelegate

import UserNotifications

class HomeViewController: UIViewController
{
    override func viewDidLoad() {
        super.viewDidLoad()

        let application = UIApplication.shared

        registerPushNotification(application)
    }



    func registerPushNotification(_ application: UIApplication){

            UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in

                if granted {
                    print("Notification: Granted")

                } else {
                    print("Notification: not granted")

                }
            }

            application.registerForRemoteNotifications()
        }

}



extension HomeViewController{

    // Called when APNs has assigned the device a unique token
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Convert token to string
        let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

        // Print it to console
        print("APNs device token: \(deviceTokenString)")

        // Persist it in your backend in case it's new
    }

    // Called when APNs failed to register the device for push notifications
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        // Print the error to console (you should alert the user that registration failed)
        print("APNs registration failed: \(error)")
    }

    // Push notification received
    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
        // Print notification payload data
        print("Push notification received: \(data)")
    }
}
Share:
12,573
user2492064
Author by

user2492064

Updated on July 11, 2022

Comments

  • user2492064
    user2492064 almost 2 years

    Everything I have seen thus far indicates that I would setup a push notification alert in my AppDelegate. However, my app requires that the user goes through a registration process, and I do not want to ask the user if they would like to receive push notifications unless the user has arrived on the viewController that appears after the registration process is complete.

    Am I able to put some of this code in the viewDidLoad method of a view controller other than my app delegate? Do I need to leave those two bottom methods "didRegisterForRemoteNotificationsWithDeviceToken" and "didReceiveRemoteNotification" in my app delegate or should I move them to wherever I try to register for remote notifications?

    I am registering for push notifications in my app with the blocks of code below:

    In the didFinishLaunchingWithOptions method of my app delegate:

    [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
                                                    UIRemoteNotificationTypeAlert|
                                                    UIRemoteNotificationTypeSound];
    

    Methods added in my app delegate:

    - (void)application:(UIApplication *)application
            didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        // Store the deviceToken
    }
    
    - (void)application:(UIApplication *)application 
            didReceiveRemoteNotification:(NSDictionary *)userInfo {
        //handle push notification
    }
    

    The resources I have visited indicate that this block of code

  • Erkam KUCET
    Erkam KUCET about 5 years
    don't working extension functions. How do automatic call function in extensions?
  • khjfquantumjj
    khjfquantumjj almost 5 years
    this method does not register for push notifications, it only requests "to interact with the user when local and remote notifications are delivered to the user's device" and should be called "before scheduling any local notifications and before registering with the Apple Push Notification service". Source: developer.apple.com/documentation/usernotifications/…