Hongxu Jin
Hongxu Jin

Reputation: 807

Can't present ViewController correctly on notification tapped

I'm using Objective-C. I want to present an infoViewController with content from a notification.

Here is my code:

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    [self presentViewControllerWithUserInfo:userInfo];
}


- (void)presentViewControllerWithUserInfo:(NSDictionary *)userInfo {
    infoViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"info"];
    vc.infoString = [[userInfo objectForKey:@"info"] objectForKey:@"string"];

    //NSLog(@"class: %@", [self.window.rootViewController class]);

    [self.window.rootViewController presentViewController:vc animated:YES completion:nil];
}

I present the infoViewController by the rootViewController. But what if the App enters background when it's not in the rootViewController? The construct looks like this: enter image description here

The App enters into background when it's in the "Another Page", and I sent a Notification to my App. When I try to open my App from the notification. The console told me this:enter image description here

And fail to present infoViewController. Someone plz help me.

Upvotes: 0

Views: 47

Answers (3)

Chandan
Chandan

Reputation: 757

call method with some delay. try this.

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//code to be executed on the main queue after delay
[self presentViewControllerWithUserInfo:userInfo];
});

Upvotes: 0

lubilis
lubilis

Reputation: 4170

Error log is telling you that you're trynig to present InfoViewController from a controller that is not in foreground, and it's right because the other controller has been presented.

My solution for this:

  1. Create a BaseViewController class (if you don't have yet) that should be extended from all controllers of your application.
  2. Create a static UIViewController property in BaseViewController called CURRENT_CONTROLLER.
  3. Set CURRENT_CONTROLLER = self in viewDidAppear() method.
  4. Remember to call always super.viewDidAppear() if you override this method in any view controller.

Then, when you receive remote notification do something like this:

infoViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"info"];
vc.infoString = [[userInfo objectForKey:@"info"] objectForKey:@"string"];

if (BaseViewController.CURRENT_CONTROLLER != nil) {
    [BaseViewController.CURRENT_CONTROLLER presentViewController:vc animated:YES completion:nil];
} else {
    // app just started, your code works well
    // this code could never be executed if you extend BaseViewController from all your view controllers
}

Upvotes: 1

Suhas Arvind Patil
Suhas Arvind Patil

Reputation: 1750

i think when you quit your application the didReceiveRemoteNotification method not gets called when you tap on the notification, instead the method didFinishLaunchingWithOptions gets called there you have to check weather application is launched by notification

Put below code in your didFinishLaunchingWithOptions :

 NSDictionary *launchOptionDict = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if (launchOptionDict) {
       [self presentViewControllerWithUserInfo:launchOptionDict];
    }

Upvotes: 0

Related Questions