application didReceiveLocalNotification not fired iOS7 application didReceiveLocalNotification not fired iOS7 xcode xcode

application didReceiveLocalNotification not fired iOS7


Is your application in the background or foreground? If it's in the foreground, I'm pretty sure that method is called. If it isn't, maybe you aren't putting that method in your application delegate.

If it's on the background, here's a few possible scenarios:

  1. Your app has been killed by the user or the OS. In this case when the user wake up your app by tapping on the notification on the notification centre (or swiping in lock screen), your application delegate will have the application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method called. You can get the notification from this method by:

    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

  2. Your app is in background, and the user tap on the notification in notification centre or lock screen. In this case, no delegate methods will be called. The documentation specifically said that didReceiveLocalNotification: is for when the app is in the foreground:

If the app is running in the foreground, there is no alert, badging, or sound; instead, the application:didReceiveLocalNotification: method is called if the delegate implements it.

So hopefully you can make an informed decision about what to do when you receive the notification. I personally find it a little bit weird that we don't get the notification object when the user launches the app by tapping the icon (not the notification). But I currently just write my logic around it.


Apple explicitly mentions in their documentation (Local and Remote Notification Programming Guide) that different methods get called depending on what state the app is in and what action the user takes (as Enrico mentioned).

Summary:

  • The user taps a custom action button in an iOS 8 notification.In this case, iOS calls either application:handleActionWithIdentifier:forRemoteNotification:completionHandler: or application:handleActionWithIdentifier:forLocalNotification:completionHandler:. In both methods, you get the identifier of the action so that you can determine which button the user tapped. You also get either the remote or local notification object, so that you can retrieve any information you need to handle the action.
  • The user taps the default button in the alert or taps (or clicks) the app icon. ... the system launches the app and the app calls its delegate’s application:didFinishLaunchingWithOptions: method, passing in the notification payload (for remote notifications) or the local-notification object (for local notifications). ...
  • The notification is delivered when the app is running in the foreground. The app calls the UIApplicationDelegate method application:didReceiveLocalNotification: or application:didReceiveRemoteNotification:fetchCompletionHandler:.

So didReceiveLocalNotification is only fired when the app is already running and is in the foreground. You should also handle the second scenario where the isn't running, for which apple has the following code example:

Objective-C:

- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];    if (localNotif) {        NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];        [viewController displayItem:itemName];  // custom method        app.applicationIconBadgeNumber = localNotif.applicationIconBadgeNumber-1;    }    [window addSubview:viewController.view];    [window makeKeyAndVisible];    return YES;}

Swift (approximation provided by myself):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {    if let localNotification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {            if let itemName = localNotification.userInfo?[ToDoItemKey] as? String {                handleNotification(localNotification)                application.applicationIconBadgeNumber = localNotification.applicationIconBadgeNumber - 1            }    }    .    .    .}