美文网首页
NotificationServiceExtension + 调

NotificationServiceExtension + 调

作者: 不胜 | 来源:发表于2019-06-21 15:47 被阅读0次

    需求:在推送的时候带上一张图.

    服务端:

    发送指定格式的推送负载,(指定 "mutable-content":1),与移动端约定指定的键值,这里我们采用的数据格式是

    {
      "aps":{
        "alert":{
          "title":"iOS 10 title",
          "subtitle":"iOS 10 subtitle",
          "body":"iOS 10 body"
        },
        "my-attachment":"https://qlogo4.store.qq.com/qzone/576014231/576014231/50?1552974221",
        "mutable-content":1,
        "category":"myNotificationCategory1",
        "sound":"default",
        "badge":3
      }
    }
    

    测试方式通过使用 Easy APNs Provider. App Store搜索可以直接下载,使用方式简单,添加token及证书即可.

    tip: 添加token时,可以直接获取设备的deviceToken(Data类型),直接输出其string类型后去掉尖括号和空格即可.

    移动端

    通过添加新的target( NotificationServiceExtension), 在 didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)方法中将下载好的资源,装载进attachments中.

    代码如下

    import UserNotifications
    import UIKit
    
    class NotificationService: UNNotificationServiceExtension {
    
        var contentHandler: ((UNNotificationContent) -> Void)?
        var bestAttemptContent: UNMutableNotificationContent?
    
        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]"
                if let aps = bestAttemptContent.userInfo["aps"] as? [String: Any], let imageUrlString = aps["my-attachment"] as? String, let imageUrl = URL(string: imageUrlString) {
                    let session = URLSession(configuration: URLSessionConfiguration.default)
                    let task = session.dataTask(with: imageUrl) { [weak self](data, response, error) in
                        guard let self = self else { return }
                        if let _ = error {
                            
                        }
                        else {
                            let path = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first!  + "/logo.png"
                            if let data = data, let image = UIImage(data: data) {
                                let imageData = image.jpegData(compressionQuality: 0.1)
                                do {
                                    try imageData?.write(to: URL(fileURLWithPath: path), options: .atomic)
                                }
                                catch {
                                    debugPrint(error.localizedDescription)
                                }
                            }
                            
                            do {
                                let attachment = try UNNotificationAttachment(identifier: "remote-attachImage", url: URL(fileURLWithPath: path), options: nil)
                                self.bestAttemptContent?.attachments = [attachment]
                            } catch {
                                debugPrint(error.localizedDescription)
                            }
                        }
                        self.contentHandler?(bestAttemptContent)
                    }
                    task.resume()
                }
            }
        }
        
        override func serviceExtensionTimeWillExpire() {
            // Called just before the extension will be terminated by the system.
            // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
            if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
                contentHandler(bestAttemptContent)
            }
        }
    
    }
    

    调试

    将target调为自己创建的NotificationService,选择Xcode的 Debug->Attach to Process by PID or Name, 然后 PID or Name项填入创建的Service的名称. 点击Attach.
    然后点击运行,选择依附的app.

    现在就可以在程序进入后台的时候,用 Easy APNs Provider 发送推送. 然后可以在 didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)中打断点 进行调试

    相关文章

      网友评论

          本文标题:NotificationServiceExtension + 调

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