可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
When I send a push notification and my app is open or in the background and I click on the push notification, my application redirects to PushMessagesVc
viewController
(as intended)
I use the code as below for this:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; PushMessagesVc *pvc = [mainstoryboard instantiateViewControllerWithIdentifier:@"PushMessagesVc"]; [self.window.rootViewController presentViewController:pvc animated:YES completion:NULL]; }
There is no problem in the code/scenario above but if the application is closed and I click on a push notification, the application does not redirect my PushMessagesVc
viewController
in this case & the application stays on the main screen.
For the 2nd scenario, I use the following code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { sleep(1); [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)]; [UIApplication sharedApplication].applicationIconBadgeNumber = 1; NSDictionary *userInfo = [launchOptions valueForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]; NSDictionary *apsInfo = [userInfo objectForKey:@"aps"]; if(apsInfo) { UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; PushMessagesVc* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:@"PushMessagesVc"]; [self.window.rootViewController presentViewController:pvc animated:YES completion:NULL]; return YES; } return YES; }
But in this case, the PushMessagesVc
does not appear.
回答1:
Since you only want to present a viewController
when you get a Push Notification, you may try utilizing NSNotificationCenter
for your purposes:
Part 1: Set up a class (in your case, the rootViewController
) to listen/respond to a NSNotification
Suppose, MainMenuViewController
is the rootViewController
of your navigationController
.
Set up this class to listen to a NSNotification
:
- (void)viewDidLoad { //... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(presentMyViewOnPushNotification) name:@"HAS_PUSH_NOTIFICATION" object:nil]; } -(void)presentMyViewOnPushNotification { //The following code is no longer in AppDelegate //it should be in the rootViewController class (or wherever you want) UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; PushMessagesVc *pvc = [mainstoryboard instantiateViewControllerWithIdentifier:@"PushMessagesVc"]; [self presentViewController:pvc animated:YES completion:nil]; //either presentViewController (above) or pushViewController (below) //[self.navigationController pushViewController:pvc animated:YES]; }
Part 2: Post Notification (possible from anywhere in your code)
In your case, AppDelegate.m methods should look like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //firstly, don't sleep the thread, it's pointless //sleep(1); //remove this line if (launchOptions) { //launchOptions is not nil NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; NSDictionary *apsInfo = [userInfo objectForKey:@"aps"]; if (apsInfo) { //apsInfo is not nil [self performSelector:@selector(postNotificationToPresentPushMessagesVC) withObject:nil afterDelay:1]; } } return YES; } -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { //this method can be done using the notification as well [self postNotificationToPresentPushMessagesVC]; } -(void)postNotificationToPresentPushMessagesVC { [[NSNotificationCenter defaultCenter] postNotificationName:@"HAS_PUSH_NOTIFICATION" object:nil]; }
PS: I haven't done this for my projects (yet) but it works and is the best way i could think of doing this kinda stuff (for the moment)
回答2:
Swift 2.0 For 'Not Running' State (Local & Remote Notification)
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Handle notification if (launchOptions != nil) { // For local Notification if let localNotificationInfo = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification { if let something = localNotificationInfo.userInfo!["yourKey"] as? String { self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something)) } } else // For remote Notification if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as! [NSObject : AnyObject]? { if let something = remoteNotification["yourKey"] as? String { self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something)) } } } return true
}
回答3:
Swift 3 To get push notification Dictionary in didFinishLaunchingWithOptions when app is kill and push notification receive and user click on that
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: AnyObject] { if let aps1 = userInfo["aps"] as? NSDictionary { print(aps1) } } return true }
Push notification Dictionary will display in alert.
回答4:
Swift version:
if let localNotification: UILocalNotification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification { //launchOptions is not nil self.application(application, didReceiveLocalNotification: localNotification) }