我知道有很多次问过类似的问题。但在阅读这些主题之后,我仍然非常困惑,特别是在iOS 10中引入UNUserNotificationCenter
之后。
官方文档提到了我可以处理远程通知的3种方法:
userNotificationCenter:willPresentNotification:withCompletionHandler:
以在应用处于前台时处理通知。userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
。application:didReceiveRemoteNotification:fetchCompletionHandler:
方法。 所以,
而且,更令人困惑的是:如果应用程序处于后台,何时调用委托方法:何时收到通知消息?或当用户点击通知时?
答案 0 :(得分:13)
iOS 10及更高版本:
1) userNotificationCenter将发布通知:通常用于决定当用户已在应用内并且通知到达时该怎么做。您可以在应用程序内触发远程通知。在点击远程通知后,方法2(didReceive响应)被调用。
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
//Handle push from foreground
//When a notification arrives and your user is using the app, you can maybe notify user by showing a remote notification by doing this
completionHandler([.alert, .badge, .sound])
//To print notification payload:
print(notification.request.content.userInfo)
}
2) userNotificationCenter didReceive response :通常用于在用户点击通知后将用户重定向到应用的特定屏幕。
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//Handle push from background or closed (or even in foreground)
//This method is called when user taps on a notification
//To print notification payload:
print(response.notification.request.content.userInfo)
}
iOS 10以下:
3)应用程序didReceiveRemoteNotification :
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
//To print notification payload
print(userInfo)
if #available(iOS 10.0, *) {
}
else {
//Handle remote notifications for devices below iOS 10
if application.applicationState == .active {
//app is currently in foreground
}
else if application.applicationState == .background {
//app is in background
}
else if application.applicationState == .inactive {
//app is transitioning from background to foreground (user taps notification)
}
}
}
4)应用程序didFinishLaunchingWithOptions launchOptions :iOS 10以下设备的唯一场景是应用关闭时用户点击启动应用的通知。您必须为此方案检查以下方法。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//To print notification payload:
if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [AnyHashable: Any] {
print(notification)
}
}
LaunchOptions是一个字典,指示应用程序的原因 推出(如果有的话)。这个字典的内容可能是空的 用户直接启动应用程序的情况。
现在回答你的问题,
1)要在应用处于后台/非活动状态时处理远程通知,您必须在方法2(userNotificationCenter didReceive响应)中为iOS 10及更高版本的设备添加代码。此外,您必须对iOS 10以下的设备使用方法3(应用程序didReceiveRemoteNotification)。
2)要在iOS 10之前应用程序在前台运行时处理远程通知,请使用方法3活动状态。
答案 1 :(得分:0)
除了Ameya的出色回答外,我想指出userNotificationCenter:willPresent:notification
如果应用处于后台状态不会被调用。
我要处理iOS 10+上所有情况的完整解决方案是也使用 application:didFinishLaunchingWithOptions:launchOptions
,并检查是否处于后台状态,并在那里处理通知。但是,您的有效载荷现在还需要包含 "content-available": 1
字段)。