美文网首页
推送的简单梳理

推送的简单梳理

作者: sftoday | 来源:发表于2018-11-06 18:01 被阅读0次

    最近推送一直有一些问题,app icon的badge显示问题,推送接收处理问题等,发现自己一直不太清楚整个流程,于是从头梳理了一遍,助于理解记忆。

    一、推送接入

    application(_:didFinishLaunchingWithOptions:) 中加入如下代码

      if #available(iOS 10.0, *) {
        // version >= iOS 10
        let center = UNUserNotificationCenter.current()
        center.delegate = self
        var options: UNAuthorizationOptions = [UNAuthorizationOptions.alert, .sound, .badge]
        if #available(iOS 12.0, *) {
          // iOS12 新增加了 providesAppNotificationSettings,可视需求添加
          options = [.alert, .sound, .badge, .providesAppNotificationSettings]
        }
        // 弹出 允许授权弹窗
        center.requestAuthorization(options: options) { granted, error in
          if granted {
            // 用户允许进行通知
            center.getNotificationSettings{ (settings) in
              print("settings = \(settings)")
            }
          } else {
            // 用户点击了不允许
          }
        }
      } else {
        // iOS 8 <= version < iOS 10
        let userNotificationSettings : UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert,.sound,.badge], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(userNotificationSettings)
      }
            
      // 注册获取 device Token
      UIApplication.shared.registerForRemoteNotifications()
    

    在iOS12,UNAuthorizationOptions新增了criticalAlertprovidesAppNotificationSettingsprovisional,作用如下

      // 重要警报,可无视勿扰模式和铃声开关的限制进行提醒,适用于灾难预警等重要信息
      // 需要单独申请权限
      @available(iOS 12.0, *)
      public static var criticalAlert: UNAuthorizationOptions { get }
    
      // 在通知管理里直接进入app内部设置页面时使用(跳转需自己在代理方法中处理)
      // 代理方法为 userNotificationCenter(_:,openSettingsFor),后续会讲
      @available(iOS 12.0, *)
      public static var providesAppNotificationSettings: UNAuthorizationOptions { get }
    
      // 临时授权,通知会以隐式推送的方式推送,并带有两个权限按钮让用户自己选择之后正常推送还是关闭
      // 隐式推送:出现在通知中心并可在应用图标上出现标记,但不会显示在锁定屏幕上,不会显示横幅,也不会播放声音
      @available(iOS 12.0, *)
      public static var provisional: UNAuthorizationOptions { get }
    

    二、推送处理

    当一条推送到达手机的时候我们需要做一些处理,比如icon上的badge变动,点击推送时候的具体跳转等,这些处理的代理方法和其调用时机如下

      // 当content-available为1时可调用(即使app已被杀死),当silent_push = 1时为静默推送
      // 此方法因为可无视app是否存活调用,所以可用于推送撤销等行为,减少推送事故的发生(避免像36氪一样...),后续会讲
      func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // 需要做的操作
        // xxxx
        completionHandler(.newData)
      }
    
      // app在前台时调用
      func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // 需要做的操作
        // xxxx 
      }
    
      // 通知被点击后进入app时调用
      // 此方法内部可处理各个推送的action,后续会讲
      func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        // 需要做的操作
        // xxxx
      }
    
      @available(iOS 12.0, *)
      func userNotificationCenter(_ center: UNUserNotificationCenter!, openSettingsFor notification: UNNotification?) {
        if let trigger = notification?.request.trigger, trigger.isKind(of: UNPushNotificationTrigger.self) {
          // 从通知界面直接进入应用(通知左滑->管理->关闭...->在"xxx"中配置...->进入app)
          // 从图一入口进入调用
        }else{
          // 从通知设置界面进入应用(系统设置下面的通知页面下面的app通知页面进入app)
          // 从图二入口进入调用
        }
      }
    
    图一 图二

    ps:图上入口都是只有在添加providesAppNotificationSettings之后才会出现

    如果接入的是jpush的话,jpush的下面几个代理方法会覆盖系统的方法,将只执行jpush的方法,不执行系统的方法

    jpush代理方法

    当app在前台运行时收到通知,系统会自动调用userNotificationCenter(_:willPresent:withCompletionHandler:),不过该条通知依旧会在通知中心显示,当用户在通知中心从该通知进入app时,会再次调用userNotificationCenter(_:didReceive:withCompletionHandler:),需要注意不要对通知做重复处理

    三、进阶处理

    Background 运行

    content-available = 1时,系统可无视app存活状态调用application(_:didReceiveRemoteNotification:fetchCompletionHandler:)方法,在其它代理方法之前(需要在Xcode 中修改应用的 Capabilities 开启Remote notifications)

    静默推送

    silent_push = 1时,content-available必须为1,此时该条推送不会出现在用户任何可见区域,用户完全感知不到,badge也不会变化

    推送覆盖

    apns-collapse-id可用于推送覆盖,比如推送Aapns-collapse-id = 100发送成功之后,再次发送Bapns-collapse-id = 100,用户将会只在通知中心看到通知B(在用户未点击通知A的前提之下,参考微信的消息撤销功能)

    推送撤销

    效果:推送A发送成功之后,再次发送B去实现撤销功能,用户在通知中心将看不到A和B(在用户未点击通知A的前提之下)
    实现:A为普通推送,B需要为静默推送,并传递需要撤销的通知id,然后在代理方法中处理

      func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // 撤销通知
        if #available(iOS 10.0, *), let removeMessageId = userInfo["removeMessageId"] as? String {
          UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [removeMessageId])
        }
        completionHandler(.newData)
      }
    

    相关文章

      网友评论

          本文标题:推送的简单梳理

          本文链接:https://www.haomeiwen.com/subject/gczuxqtx.html