mani_007
mani_007

Reputation: 602

Implement didReceiveRemoteNotification to show a new viewController when push comes

I have an application that should loads a ViewController when a remote push notification comes, I have this code currently in my appDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    NSLog(@"REMOTE NOTIFICATION %@", userInfo);
    if( [[MTMAPIClient sharedClient] isLoggedIn: nil]){
        if (userInfo && userInfo[@"aps"] && userInfo[@"aps"][@"extra"]) {
            if ( application.applicationState == UIApplicationStateActive ) {
                [self playSound];
            }
        }

        [NotificationHelper pushNotificationCame:userInfo view:self.tabBarController.selectedViewController];
    }
}

My application is a tabbed application (like AppStore and iTunes) which I keep a reference to UITabBarController in my appDelegate.

My Notification Helper code is:

+ (void) pushNotificationCame:(NSDictionary*)userInfo view:(UINavigationController*) viewController
{
    NSString* otp;
    if (userInfo && userInfo[@"aps"] && userInfo[@"aps"][@"extra"]) {

        otp = (NSString*)userInfo[@"aps"][@"extra"][@"otp"];


       [Authorization loadAuthByOtp:otp
                            success:^(Authorization *auth) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryBoard" bundle:[NSBundle mainBundle]];
                                    TransactionDetailViewController* appTransactionDetailsView = [storyboard instantiateViewControllerWithIdentifier:@"transactionDetails"];
                                    appTransactionDetailsView.authorization = auth;
                                    [viewController pushViewController:appTransactionDetailsView animated:YES];
                                });

                            } failure:^(NSString *error, ErrorType errorType) {
                                NSLog(@"pushNotificationCame loadAuthByOtp failed with error: %@", error);
                            }];
    }
}

This works in 70% of scenarios, but sometimes when I sign out of application and sign back in, when a push notification comes self.tabBarController.selectedViewController and "viewController" in pushNotificationCame method is not the currently active view in my Tab Bar so PushViewController doesn't work.

In other words there are three tabs in my application tab A, B, C when push notification comes I'm on tab A but self.tabBarController.selectedViewController in debugger is B viewController so when I push a new viewController it goes to tab B and nothing happens. no error but no new viewController as well. this happens only when I sign out and sing back in to application, normally it just works!

My Sign out code:

[viewController.navigationController.tabBarController performSegueWithIdentifier:@"logoutSegue" sender:viewController];

and my sign in code:

[self performSegueWithIdentifier:@"fromSignInToApplications" sender:self];

which takes user to first tab in TabBarController.

and in AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    self.tabBarController = (UITabBarController *)self.window.rootViewController;
}

Upvotes: 1

Views: 314

Answers (1)

Wain
Wain

Reputation: 119021

It looks like the problem is that you are building up a stack of view controllers when you logout / login so at the root of the stack you have the original tab view controller and then you have logout, then login, then a new tab view controller. At this point in time the app delegate still has a reference to the original tab view controller and nothing works any more.

(note, you may not have a logout view controller, but the principle applies for the login view controller)

What you should consider doing is presenting the logout and login view controllers rather than pushing them, then, when the login is complete, rather than pushing with fromSignInToApplications you would dismiss and reveal the original tab view controller again. This also uses less memory and could result in less future issues with observation and the like.

The alternate is to post a login notification after the segue so the app delegate can get the new tab view controller - but, it isn't the window root view controller so you would need to make some changes or think about how that would work.

Upvotes: 1

Related Questions