Register for remote notifications outside of app d

2019-02-16 11:13发布

问题:

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

回答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).



回答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.



回答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.



回答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)")
    }
}