美文网首页
NotificationServiceExtension和自定义

NotificationServiceExtension和自定义

作者: sftoday | 来源:发表于2018-11-10 17:09 被阅读0次
    示例

    我们都收到过这种通知,它比普通通知内容更加丰富,可以附带图片、音频、视频等附件,下方也有各种选择项供用户选择。这其中附件功能由NotificationServiceExtension来提供和实现,选择项功能由UNNotificationActionUNNotificationCategory来提供和实现。
    ps: 这些功能均自 iOS10 及以后才提供

    一、NotificationServiceExtension

    在targets中创建Notification Service Extension,然后生成的文件中有两个方法

    didReceive(_:withContentHandler:)

    我们用来将图片或音视频包装成attachment,然后再放入通知中。

    • 图片或音视频通过通知的附加字段来传输,此时mutable-content必须为1
    • 此方法的处理时间至多为30秒,如果30秒还未处理完毕,将调用serviceExtensionTimeWillExpire()方法
    • 因为UNNotificationAttachment的初始化方法中的URL只接收FileURL,所以需要将附件先写入本地,再拿到本地URL
      override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
            
        if let bestAttemptContent = bestAttemptContent {
          // Modify the notification content here...
                        
          // 处理标题
          // bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
          // bestAttemptContent.subtitle = "this is subtitle"
                        
          // 处理附件 eg. 图片、视频、动图、音频
          // 附件最大尺寸 音频5M,图片10M,视频50M
          if let dict = bestAttemptContent.userInfo as? Dictionary<String, Any>, let urlString = dict["attachment"] as? String, let url = URL(string: urlString) {
            var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
            path!.append(contentsOf: "/" + urlString.split(separator: "/").last!.split(separator: "?").first!)
            if ((try? Data(contentsOf: url).write(to: URL(fileURLWithPath: path!))) != nil), let attachment = try? UNNotificationAttachment(identifier: "attachment", url: URL(fileURLWithPath: path!), options: nil) {
              bestAttemptContent.attachments = [attachment]
            }
          }
          contentHandler(bestAttemptContent)
        }
      }
    

    serviceExtensionTimeWillExpire()

    此方法当附件处理时间过长时会调用,之后会将通知直接展示

    调用时机

    关于UNNotificationServiceExtension,系统文档有以下说明

    Note
    You cannot modify silent notifications or those that only play a sound or badge the app’s icon.

    另外mutable-content必须为1,表示可以修改这条通知

    二、自定义notification action

    主要有UNNotificationCategoryUNNotificationAction两个类起作用。
    其中UNNotificationAction对应用户的某个选项,如 查看跟贴 等,而UNNotificationCategory下可以添加多个action,一个通知对应一个category。
    发送通知的时候需要将category参数填上想展示的对应categoryID。

    UNTextInputNotificationActionUNNotificationAction的子类,点击后可以回复本条通知,就像微信的消息回复。

      // MARK: - 通知action的处理
        
      // 配置action
      fileprivate func setupNotificationAction() {
        guard #available(iOS 10.0, *) else { return }
        // options参数:
        // .foreground             白底黑字,触发后app打开(进入前台)
        // .authenticationRequired 白底黑字,触发后不进入app
        // .destructive            白底红字,触发后不进入app
        let action1 = UNNotificationAction(identifier: notificationActionIdentifierScan, title: "查看", options: .foreground)
        let action2 = UNNotificationAction(identifier: notificationActionIdentifierDismiss, title: "不感兴趣", options: .authenticationRequired)
        let action3 = UNTextInputNotificationAction(identifier: notificationActionIdentifierReply, title: "回复", options: .authenticationRequired, textInputButtonTitle: "发送", textInputPlaceholder: "请输入内容")
            
        let category1 = UNNotificationCategory(identifier: notificationCategoryNormal, actions: [action1, action2], intentIdentifiers: [notificationActionIdentifierScan, notificationActionIdentifierDismiss], options: .customDismissAction)
        let category2 = UNNotificationCategory(identifier: notificationCategorySession, actions: [action3, action1], intentIdentifiers: [notificationActionIdentifierScan, notificationActionIdentifierReply], options: .customDismissAction)
            
        UNUserNotificationCenter.current().setNotificationCategories([category1, category2])
      }
    

    点击某个选项后进入app后依旧是调用userNotificationCenter(_:didReceive:withCompletionHandler:),所以响应处理依旧写在此方法里

      switch response.actionIdentifier {
        case notificationActionIdentifierScan:
          return
        case notificationActionIdentifierReply:
          // 获取回复内容并处理
          if let _ = (response as? UNTextInputNotificationResponse)?.userText {
                    
          }
          return
        case notificationActionIdentifierDismiss:
          return
        default:
          return
       }
    

    相关文章

      网友评论

          本文标题:NotificationServiceExtension和自定义

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