10

问题:

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

有时不会在 iOS7 中调用。我们如何安排通知并不重要:

alarm.fireDate = [[NSDate date] dateByAddingTimeInterval:0.1];
[app scheduleLocalNotification:alarm];

或者:

[app presentLocalNotificationNow:alarm];

我的想法:这发生在用户在通知警报动画完成之前滑动的情况下。如果他在滑动前只等待半秒钟 - 通知就会被触发并且应用程序会按预期进行。问题可能是应用程序在收到通知之前进入前台。

有人遇到这个吗?它是一个错误吗?有什么解决办法吗?谢谢!

4

2 回答 2

14

您的应用程序是在后台还是前台?如果它在前台,我很确定该方法已被调用。如果不是,也许您没有将该方法放入您的应用程序委托中。

如果它在后台,这里有一些可能的情况:

  1. 您的应用程序已被用户或操作系统杀死。在这种情况下,当用户通过点击通知中心的通知(或在锁定屏幕中滑动)唤醒您的应用程序时,您的应用程序委托将application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions调用该方法。您可以通过以下方式从此方法获取通知:

    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

  2. 您的应用程序在后台,用户点击通知中心或锁定屏幕中的通知。在这种情况下,不会调用委托方法。该文档特别指出,这didReceiveLocalNotification:是针对应用程序处于前台时的情况:

如果应用程序在前台运行,则没有警报、标记或声音;相反,如果委托实现它,则调用 application:didReceiveLocalNotification: 方法。

因此,希望您能在收到通知时就该做什么做出明智的决定。我个人觉得当用户通过点击图标(而不是通知)启动应用程序时我们没有得到通知对象有点奇怪。但我目前只是围绕它写我的逻辑。

于 2013-10-09T11:45:09.443 回答
8

Apple 在他们的文档(本地和远程通知编程指南)中明确提到,根据应用程序所处的状态和用户采取的操作(如 Enrico 所述),调用不同的方法。

概括:

  • 用户点击 iOS 8 通知中的自定义操作按钮。 在这种情况下,iOS 调用 application:handleActionWithIdentifier:forRemoteNotification:completionHandler: 或 application:handleActionWithIdentifier:forLocalNotification:completionHandler:。在这两种方法中,您都可以获得操作的标识符,以便您可以确定用户点击了哪个按钮。您还可以获取远程或本地通知对象,以便您可以检索处理操作所需的任何信息。
  • 用户点击警报中的默认按钮或点击(或单击)应用程序图标。...系统启动应用程序,应用程序调用其委托的 application:didFinishLaunchingWithOptions: 方法,传入通知负载(用于远程通知)或本地通知对象(用于本地通知)。...
  • 当应用程序在前台运行时发送通知。应用调用 UIApplicationDelegate 方法 application:didReceiveLocalNotification: 或 application:didReceiveRemoteNotification:fetchCompletionHandler:。

所以 didReceiveLocalNotification 仅在应用程序已经运行并处于前台时才会触发。您还应该处理没有运行的第二种情况,苹果有以下代码示例:

目标-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(我自己提供的近似值):

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
            }
    }
    .
    .
    .
}
于 2015-01-19T08:11:35.160 回答