xcode 应用程序 didReceiveLocalNotification 未触发 iOS7

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19244066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:02:58  来源:igfitidea点击:

application didReceiveLocalNotification not fired iOS7

iphonexcodeios7uilocalnotification

提问by Asen Kasimov

The problem:

问题:

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

is not called sometimes with iOS7. It doesn't mater how we schedule the notification:

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

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

or:

或者:

[app presentLocalNotificationNow:alarm];

My thoughts: This happens in the case when the user slides before the notification alert animation is finished. And if he waits just a half second before he slides - the notification is fired and the App proceeds as expected. The problem probably is that application enters foreground before the notification is received.

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

Did anyone meet this? Is it a bug? Any solution? Thank you!

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

回答by Enrico Susatyo

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 *)launchOptionsmethod 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:

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

    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

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

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.

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

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.

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

回答by ali-hk

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).

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

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

所以 didReceiveLocalNotification 只在应用程序已经运行并且在前台时才会被触发。您还应该处理未运行的第二种情况,对于该情况,apple 具有以下代码示例:

Objective-C:

目标-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):

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
            }
    }
    .
    .
    .
}