【问题标题】:In which method should I handle iOS remote notification?我应该用哪种方法处理 iOS 远程通知?
【发布时间】:2018-03-27 05:59:21
【问题描述】:

我知道类似的问题已经被问过很多次了。但是在阅读了这些帖子之后,我仍然感到非常困惑,尤其是在 iOS 10 中引入了UNUserNotificationCenter 之后。

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

  1. 实现userNotificationCenter:willPresentNotification:withCompletionHandler: 以在应用处于前台时处理通知。
  2. 在应用处于后台或未运行时实现userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
  3. 但文档中也提到:在iOS和tvOS中,系统将通知负载传递给app delegate的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


    【解决方案1】:

    iOS 10 及更高版本:

    1) userNotificationCenter willPresent 通知: 一般用于决定当用户已经在应用内并且通知到达时要做什么。您可能会在应用程序内触发远程通知。用户点击远程通知后,方法 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活动状态。

    【讨论】:

    • 亲身体验后,使用iOS 10及以上的设备,如果没有实现userNotificationCenter didReceive response,则会触发application didReceiveRemoteNotification
    【解决方案2】:

    除了 Ameya 的出色回答之外,我想指出 userNotificationCenter:willPresent:notification 如果应用程序处于后台状态,则不会被调用

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      相关资源
      最近更新 更多