iPhone 7
iPhone 7

Reputation: 1741

How to redirect to particular view controller from push notification when app is in terminated mode

I need to redirect the app to particular view controller from push notification received. But yet, i am not able to get which delegate method will be called. Please guide.

Below is the code i have tried so far. i have tried in didFinishLaunchingWithOptions but doesn't working.

 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(notificationClickedInNotificationPanel:)
                   withObject:userInfo
                   afterDelay:1];
    }
}

Upvotes: 1

Views: 1231

Answers (4)

Michael Dougan
Michael Dougan

Reputation: 1698

You should do it both in didFinishLaunchingWithOptions and didReceiveRemoteNotification, they are called at different times. The first is called when the app is completely closed when the notification is clicked, the second is called when the app is open and in use.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (launchOptions != nil)
    {
        NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (dictionary != nil)
        {

            self.animal_id = [dictionary objectForKey:@"animal_id"];
            self.notificationText = [dictionary objectForKey:@"alert"];
            self.soundFile = [dictionary objectForKey:@"sound"];

            if ([self.animal_id length] > 0) {

                NSInteger numberOfBadges = [UIApplication sharedApplication].applicationIconBadgeNumber;
                numberOfBadges -=1;

                if (numberOfBadges < 0) {
                    numberOfBadges = 0;
                }

                [[UIApplication sharedApplication] setApplicationIconBadgeNumber:numberOfBadges];

                doNotShowAlert = YES;
                [self showPetDetails:self.animal_id];
            } else {
                doNotShowAlert = NO;
            }

        }

    }

    return YES;
}

And Here:

-(void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo
{

    NSInteger numberOfBadges = [UIApplication sharedApplication].applicationIconBadgeNumber;
    numberOfBadges -=1;

    if (numberOfBadges < 0) {
        numberOfBadges = 0;
    }

    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:numberOfBadges];

    self.animal_id  = [userInfo objectForKey:@"animal_id"];

    NSDictionary *aps = [userInfo objectForKey:@"aps"];

    self.notificationText = [aps objectForKey:@"alert"];
    self.soundFile = [aps objectForKey:@"sound"];

   [self showPetDetails:self.animal_id];
}

showPetDetails goes out to the database to get the detail information to display. When it has it, it calls another method to display the detail view:

PetDetailViewController *notificationController = [self.rootNavigationController.storyboard instantiateViewControllerWithIdentifier:@"petdetail"];
notificationController.petDetail = petDetail;
notificationController.currentImage = nil;

[self.rootNavigationController pushViewController:notificationController animated:YES];

Upvotes: 0

Michael Henry
Michael Henry

Reputation: 720

When the app has killed, You can find the push notification payload from the launchOptions

Here is the reference for more info: https://developer.apple.com/documentation/uikit/uiapplication/launchoptionskey/1622967-remotenotification

Upvotes: 0

Bug Hunter Zoro
Bug Hunter Zoro

Reputation: 1915

I did something very recently, but it's in Swift but should be very similar if you want to do this in OC.

Hint: didReceiveRemoteNotification will not get called if your app is terminated, the only method that gets called is didFinishLaunchingWithOptions

Inside the didFinishLaunchingWithOptions you can do something like this

if let launchOpts = launchOptions as [UIApplication.LaunchOptionsKey: Any]? {
            if let notificationPayload = launchOpts[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary {

                 let apsBody = notificationPayload["aps"] as? NSDictionary
                 if(apsBody != nil){
                 // here you can either read value from the `apsBody` dictionary 
                //OR just push the respective controller you want to push
                 }
            }
        }else{
           //go with the regular flow
        }

Do know this when your app is terminated you have no instance of navigationController so you might want to make sure you have an instance of a navigation controller to push your view.

Hope that helps

Upvotes: 2

Friend
Friend

Reputation: 125

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

// Called when App is in Foreground // Using the data received in the notification you can call the desired view controller

    completionHandler([.alert, .badge, .sound])
}

and,

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

// Called when App is not in  Foreground // Using the data received in the notification you can call the desired view controller
    completionHandler()
}

Upvotes: 1

Related Questions