ios 检测应用程序是否:didReceiveRemoteNotification: fetchCompletionHandler: 通过点击通知中心的通知来调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23168345/
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
Detect if application: didReceiveRemoteNotification: fetchCompletionHandler: was called by tapping on a notification in Notification Center
提问by Devfly
application: didReceiveRemoteNotification: fetchCompletionHandler:
is different from
不同于
application: didReceiveRemoteNotification:
How? from the docs:
如何?从文档:
Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running, the system calls this method regardless of the state of your app. If your app is suspended or not running, the system wakes up or launches your app and puts it into the background running state before calling the method. If the user opens your app from the system-displayed alert, the system calls this method again so that you know which notification the user selected.
与 application:didReceiveRemoteNotification: 方法不同,该方法仅在您的应用程序运行时调用,无论您的应用程序处于何种状态,系统都会调用此方法。如果您的应用程序暂停或未运行,系统会在调用该方法之前唤醒或启动您的应用程序并将其置于后台运行状态。如果用户从系统显示的警报中打开您的应用,系统会再次调用此方法,以便您知道用户选择了哪个通知。
My struggle is: I want to know if the method was called by the user tapping an a system-displayed alert from the Notification Center or from a silent push notification that wakes up the device. Currently, as far as I can see, there is no obvious way to differentiate.
我的挣扎是:我想知道该方法是由用户点击来自通知中心的系统显示警报还是来自唤醒设备的无声推送通知调用的。目前,据我所知,没有明显的区分方法。
- (BOOL)application: didFinishLaunchingWithOptions:
Tracking the launchOptionsin the above method is not a solution because it's only called if the app is suspended/not running in background. If it's running in the background it doesn't get called.
在上述方法中跟踪launchOptions不是解决方案,因为只有在应用程序暂停/不在后台运行时才会调用它。如果它在后台运行,则不会被调用。
回答by race_carr
The Apple docs are a bit confusing
Apple 文档有点混乱
application: didReceiveRemoteNotification: fetchCompletionHandler:
is used if your application supports the remote-notification background mode (ie you're doing BackgroundFetch.)
如果您的应用程序支持远程通知后台模式(即您正在执行 BackgroundFetch),则使用。
application: didReceiveRemoteNotification:
is called when the OS receives a RemoteNotification and the app is running (in the background/suspended or in the foreground.)
You can check the UIApplicationState to see if the app was brought to foreground by the user (tapping on notification) or was already running when notification comes in.
当操作系统收到 RemoteNotification 并且应用程序正在运行(在后台/挂起或前台)时调用。
您可以检查 UIApplicationState 以查看应用程序是否被用户带到前台(点击通知)或已经通知进来时运行。
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState state = [application applicationState];
// user tapped notification while app was in background
if (state == UIApplicationStateInactive || state == UIApplicationStateBackground) {
// go to screen relevant to Notification content
} else {
// App is in UIApplicationStateActive (running in foreground)
// perhaps show an UIAlertView
}
}
回答by Rivera
You could check the UIApplication
's applicationState
to distinguish silent calls from calls made with the application being actively used by the user:
您可以检查UIApplication
'sapplicationState
以区分无声呼叫和用户正在使用的应用程序进行的呼叫:
typedef enum : NSInteger {
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
} UIApplicationState;
Or keep your own flag set on the delegate
's applicationDidEnterBackground:
.
或者在delegate
's上设置自己的标志applicationDidEnterBackground:
。
回答by overunder
Application State is not reliable because if you have control center or Apple's notification center open over your app, application: didReceiveRemoteNotification: fetchCompletionHandler: will get called and the application state will be Inactive.
应用程序状态不可靠,因为如果您在应用程序上打开了控制中心或 Apple 的通知中心, application: didReceiveRemoteNotification: fetchCompletionHandler: 将被调用并且应用程序状态将为 Inactive。
I'm having the same issue trying to respond to a click on the notification while the app is in the background and there doesn't seem to be a reliable way to solely identify this.
我遇到了同样的问题,试图在应用程序处于后台时响应点击通知,似乎没有可靠的方法来单独识别这一点。
回答by Ghulam Rasool
In case of swift
快速的情况下
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let state : UIApplicationState = application.applicationState
if (state == .Inactive || state == .Background) {
// go to screen relevant to Notification content
} else {
// App is in UIApplicationStateActive (running in foreground)
}
}
回答by Alexey Kozhevnikov
When application: didReceiveRemoteNotification:fetchCompletionHandler:
method is called app state is UIApplicationStateInactive
if user taps on alert (in this case you would like to prepare some UI) and is UIApplicationStateBackground
when app is silently woken (in this case you just load some data).
当application: didReceiveRemoteNotification:fetchCompletionHandler:
方法被调用时,应用程序状态是UIApplicationStateInactive
用户点击警报(在这种情况下您想要准备一些 UI)以及UIApplicationStateBackground
应用程序被静默唤醒时(在这种情况下您只需加载一些数据)。
回答by navkast
I'm not sure if I understand your question.
我不确定我是否理解你的问题。
Do you want to differentiate between a silent push notification background fetch and a noisy push notification? You can simply check whether the push notification dictionary contains the "content-available" key: [[userInfo objectForKey:@"aps"] objectForKey:@"content-available"]
If it does, then it should be a silent push. If not, it was a normal push.
您想区分静默推送通知后台获取和嘈杂推送通知吗?您可以简单地检查推送通知字典是否包含“content-available”键:[[userInfo objectForKey:@"aps"] objectForKey:@"content-available"]
如果包含,那么它应该是静默推送。如果没有,这是一个正常的推动。
Do you want to know if that background fetch method is called when the application receives a notification and it is in suspended/not running? If so, you can do the following:
您想知道当应用程序收到通知并且它处于暂停/未运行状态时是否调用该后台提取方法?如果是这样,您可以执行以下操作:
- Download and import LumberHymans into your app.Look through the directions and learn how to set it up such that you can save logs to the disk.
Put this in any method you want to see whether/when that method is invoked:
DDLogDebug(@"%@ - %@",NSStringFromSelector(_cmd),NSStringFromClass([self class]));
This will print the class and the method to the log file.
Examine the log file after sending yourself a push notification to your background-fetch enabled app, and see if any of the methods get called by looking at your log file.
- 下载 LumberHymans 并将其导入您的应用程序。查看说明并了解如何设置它以便您可以将日志保存到磁盘。
把它放在任何你想查看是否/何时调用该方法的方法中:
DDLogDebug(@"%@ - %@",NSStringFromSelector(_cmd),NSStringFromClass([self class]));
这会将类和方法打印到日志文件中。
在向启用后台提取的应用程序发送推送通知后检查日志文件,并通过查看日志文件查看是否调用了任何方法。
If you have set up your app correctly for background fetch, the method application: didReceiveRemoteNotification: fetchCompletionHandler:
will be called even when the app is backgrounded/not running if you receive a push notification (silent push or not).
如果您为后台获取正确设置了应用程序,application: didReceiveRemoteNotification: fetchCompletionHandler:
即使应用程序处于后台/未运行,如果您收到推送通知(静默推送与否),也会调用该方法。
回答by Giorgio
In iOS 10.0+ you can use the method
在 iOS 10.0+ 中,您可以使用该方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;
to detect when user taps on a system-displayed alert from the NotificationCenter.
检测用户何时点击来自通知中心的系统显示警报。
If you implement the method above
如果你实现了上面的方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
will be called onlywhen a notification is received- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;
will be called when user taps on notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
只有在收到通知时才会调用- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;
当用户点击通知时将被调用
回答by Alex Mason
For Swift: In application(_:didFinishLaunchingWithOptions:)
parse the application options. If they exist, you know the app was launched from them tapping.
对于 Swift:在application(_:didFinishLaunchingWithOptions:)
解析应用程序选项中。如果它们存在,您就知道该应用程序是通过点击它们启动的。
if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any] {
print("Remote notfi is \(remoteNotif)")
if let notification = remoteNotif["aps"] as? [AnyHashable : Any] {
/// - parse notification
}
}
Otherwise, you can handle the tap in, and you know that the app is open/background/inactiveapplication(_:didReceiveRemoteNotification:fetchCompletionHandler:)
否则,您可以处理点击,并且您知道该应用程序是打开的/后台的/不活动的application(_:didReceiveRemoteNotification:fetchCompletionHandler:)