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
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).
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.
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.
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)")
}
}