【问题标题】:application didReceiveLocalNotification not fired iOS7应用程序 didReceiveLocalNotification 未触发 iOS7
【发布时间】:2013-10-15 03:52:24
【问题描述】:

问题:

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

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

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

或:

[app presentLocalNotificationNow:alarm];

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

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

【问题讨论】:

  • 亲爱的,我必须说你的观察是 100% 正确的。用户必须等到通知动画完成。然后只有应用程序委托被调用。我已经对此进行了测试。我非常确定这一点。

标签: iphone xcode ios7 uilocalnotification


【解决方案1】:

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

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

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

    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

  2. 您的应用处于后台,用户点击通知中心或锁定屏幕中的通知。在这种情况下,没有delegate methods will be called。文档特别说didReceiveLocalNotification:是应用在前台时的:

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

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

【讨论】:

  • 感谢 Enrico Susatyo 的回复!当用户在通知滑块上滑动时,应用程序处于后台。(它是一个 voip 应用程序)并且应用程序没有终止。正如我指出的那样,用户应该在通知到来的第一刻滑动。只有这样 didReceiveLocalNotification 才不会被触发。相同的代码在 iOS6 上完美运行。应用程序 didReceiveLocalNotification 属于 AppDelegate。
  • Enrico 我将您的答案标记为有用但不是已接受的答案,因为它不能完全回答我的问题。我现在几乎可以肯定,如果用户在通知出现后的第一刻滑动,应用程序仍处于后台并且应用程序 didReceiveLocalNotification 不会被触发。
  • 当然。我希望我们都能找到没有触发 didReceiveLocalNotification 的原因。但基本上我是在假设苹果已经做出改变并且不会再解雇它的情况下工作的。这就是我解释文档的方式。
  • @EnricoSusatyo 如果应用程序在后台并且用户点击图标而不是通知,您是否找到任何解决方案?在这种情况下,我们如何识别已收到通知?因为didReceiveLocalNotification 在这种情况下没有调用?
【解决方案2】:

Apple 在其文档 (Local and Remote Notification Programming Guide) 中明确提到,根据应用所处的状态和用户采取的操作(如 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
            }
    }
    .
    .
    .
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 2018-04-13
    相关资源
    最近更新 更多