NotificationServiceExtension + 调试

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

服务端:

发送指定格式的推送负载,(指定 "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 + 调试)