Search code examples
ioscocoa-touchstoryboardpush-notification

Push Notification -didFinishLaunchingWithOptions


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.


Solution

  • 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)