我应该在哪种方法处理iOS远程通知?

时间:2017-10-15 17:38:55

标签: ios swift push-notification notifications

我知道有很多次问过类似的问题。但在阅读这些主题之后,我仍然非常困惑,特别是在iOS 10中引入UNUserNotificationCenter之后。

官方文档提到了我可以处理远程通知的3种方法:

  1. 实施userNotificationCenter:willPresentNotification:withCompletionHandler:以在应用处于前台时处理通知。
  2. 当应用处于后台或未运行时实施userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
  3. 但文档还提到:在iOS和tvOS中,系统将通知有效负载传递给app委托的application:didReceiveRemoteNotification:fetchCompletionHandler:方法。
  4. 所以,

    • 要在应用处于后台/非活动状态时处理远程通知,我应该将代码放在3中的应用委托方法中,还是将通知中心委托放在2中?由于UNUserNotificationCenter仅适用于iOS> 10,我应该编写不同的代码来处理每个案例吗?
    • 大约1,它仅在iOS 10之后可用。当iOS 10之前的应用程序在前台运行时,如何处理远程通知?

    而且,更令人困惑的是:如果应用程序处于后台,何时调用委托方法:何时收到通知消息?或当用户点击通知时?

    相关:iOS push notification: how to detect if the user tapped on notification when the app is in background?

2 个答案:

答案 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字段)。