Belle B. Cooper
Belle B. Cooper

Reputation: 395

UILocalNotification doesn't trigger didReceiveLocalNotification when tapping from Notification Center

I'm using Objective-c to create a UILocalNotification in my iPhone app. I'm targeting iOS 8 and using XCode 6.

My problem relates to handling UILocalNotification when app is not running and it's opened by tapping on a notification. When the user taps the notification and opens the app I use didReceiveLocalNotification in AppDelegate.m to show a particular View Controller and send the VC some data (a date).

This works fine when tapping the notification from the lockscreen. When tapping the notification in the Notification Center didReceiveLocalNotification is never called. I used a UIAlertView to test this on my device. didFinishLaunchingWithOptions is called, but when I include the code to show the particular View Controller in that method it never works (though another UIAlertView showed me it was running that part of the code, just never completing the showViewController method).

Here's my didFinishLaunchingWithOptions code:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([UIApplication sharedApplication].scheduledLocalNotifications.count >= 1) {

        // Handle local notification received if app wasn't running in background
        UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

        if ([[notification.userInfo objectForKey:@"notification"]  isEqual:@"mood rating"]) {
            // Create reportVC
                    NSLog(@"launched app and about to show reportvc");
            ReportViewController *reportVC = (ReportViewController *)[self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"reportVC"];

            // Date stuff goes here - code removed

            // show the reportVC
            [self.window.rootViewController showViewController:reportVC sender:self];
        }
    } else {
        [self createLocalNotification];
    }

    return YES;
}

And here is my didReceiveLocalNotification code:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

        // Create report view
        ReportViewController *reportVC = (ReportViewController *)[self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"reportVC"];

        // Same date stuff goes here as in didFinishLaunchingWithOptions

        // Show report vc
        [self.window.rootViewController showViewController:reportVC sender:self];
}

The date stuff that I've take out is just checking if it's after 9pm or not, and either creating today's date or yesterday's, and then setting the result as a property of the reportVC. Let me know if that's relevant and I'll add it back in.

So here's some stuff I've tried to fix this:

And in case this is screwing it up, here's how I'm testing this at the moment:

I add these two lines to the didFinishLaunchingWithOptions method:

[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self createLocalNotification];

I change the scheduled time for the notification to be about 3 minutes into the future. It's normally set to go off at 9pm every night using date components like this:

dateComponents.hour = 21;
dateComponents.minute = 0;

And I change the notification's repeatInterval to be NSCalendarUnitMinute instead of NSCalendarUnitDay which is what it's set to for release builds.

Then I run the app on my device using XCode, and stop it once it's run and scheduled the notification. I run it again without these two lines:

[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self createLocalNotification];

And then stop the app from XCode, open multitasking on my device, swipe the app up to close it, and wait for a notification to arrive. After tapping each test notification I multitask and close the app again so I can test from a totally closed app each time.

Upvotes: 4

Views: 987

Answers (1)

Nikolay Mamaev
Nikolay Mamaev

Reputation: 1474

You may want to try this (present your view controller asynchronously with the dispatch_async()):

if ([[notification.userInfo objectForKey:@"notification"]  isEqual:@"mood rating"]) {

    dispatch_async(dispatch_get_main_queue(), ^{

        // Create reportVC
                NSLog(@"launched app and about to show reportvc");
        ReportViewController *reportVC = (ReportViewController *)[self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"reportVC"];

        // Date stuff goes here - code removed

        // show the reportVC
        [self.window.rootViewController showViewController:reportVC sender:self];
    });
}

or this (call [self.window makeKeyAndVisible] before presenting your view controller):

if ([[notification.userInfo objectForKey:@"notification"]  isEqual:@"mood rating"]) {
    // Create reportVC
            NSLog(@"launched app and about to show reportvc");
    ReportViewController *reportVC = (ReportViewController *)[self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"reportVC"];

    // Date stuff goes here - code removed

    // show the reportVC
    [self.window makeKeyAndVisible];
    [self.window.rootViewController showViewController:reportVC sender:self];
}

Upvotes: 1

Related Questions