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

问题描述 投票:8回答:2

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

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

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

所以,

  • 要在应用程序处于后台/非活动状态时处理远程通知,我应该将我的代码放在3中的应用程序委托方法中,还是2中的notificationCenter委托中?由于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?

ios swift push-notification notifications
2个回答
15
投票

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响应:通常用于在用户点击通知后将用户重定向到应用的特定屏幕。

@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以下设备的唯一场景是关闭app并且用户点击启动应用程序的通知。您必须为此方案检查以下方法。

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活动状态。


0
投票

除了Ameya的出色答案之外,我还想指出,如果app处于背景状态,userNotificationCenter:willPresent:notification就不会被调用。

我在iOS 10+上处理所有案例的完整解决方案是使用application:didFinishLaunchingWithOptions:launchOptions,并检查是否处于后台状态,并在那里处理通知。但是,您的有效负载现在还需要包含"content-available": 1字段。

© www.soinside.com 2019 - 2024. All rights reserved.