0

我写了一个UNNotificationServiceExtension我试图下载文件并附加它的地方。每次我跑步我都会得到一个例外说

附件文件 URL 无效。

我一生都无法弄清楚为什么会失败。

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    let bestAttemptContent = request.content.mutableCopy() as! UNMutableNotificationContent

    guard let urlPath = request.content.userInfo["media-url"] as? String,
        let url = URL(string: urlPath) else {
            contentHandler(bestAttemptContent)
            return
    }

    let semaphore = DispatchSemaphore(value: 0)

    URLSession.shared.downloadTask(with: url) {
        location, _, _ in

        defer { semaphore.signal() }

        guard let location = location else { return }

        var destination: URL!

        do {
            destination = try FileManager.default.url(for: .itemReplacementDirectory,
                                                      in: .userDomainMask,
                                                      appropriateFor: location,
                                                      create: true)
            destination.appendPathComponent(url.lastPathComponent)
            let attachment = try UNNotificationAttachment(identifier: "",
                                                          url: destination)
            bestAttemptContent.attachments = [attachment]
        } catch let error {
            bestAttemptContent.body = error.localizedDescription + "\n" + destination.absoluteString
        }
    }.resume()

    _ = semaphore.wait(timeout: .distantFuture)

    contentHandler(bestAttemptContent)
}
4

1 回答 1

1

如果您仍在寻找代码,这里是,

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)

        func failEarly() {
            contentHandler(request.content)
        }

        guard let content = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
            return failEarly()

        }
        guard let apnsData = content.userInfo["data"] as? [String: Any] else {
            return failEarly()

        }

        guard let attachmentURL = apnsData["media-url"] as? String else {
            return failEarly()

        }

        guard let imageData = NSData(contentsOf:NSURL(string: attachmentURL)! as URL) else {
            return failEarly()

        }

        bestAttemptContent?.attachments = [create(imageFileIdentifier: "image.jpg", data: imageData, options: nil)!]
        contentHandler(bestAttemptContent!)

    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}

func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {

    let tmpSubFolderName: String = ProcessInfo.processInfo.globallyUniqueString
    let fileURLPath: String = NSTemporaryDirectory()
    let tmpSubFolderURL: String = URL(fileURLWithPath: fileURLPath).appendingPathComponent(tmpSubFolderName).absoluteString

    if ((try? FileManager.default.createDirectory(atPath: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)) != nil) {
        let fileURL = URL(fileURLWithPath: tmpSubFolderURL).appendingPathComponent(imageFileIdentifier)
        data.write(to: fileURL, atomically: true)
        let attachment = try? UNNotificationAttachment(identifier: imageFileIdentifier, url: fileURL, options: options)
        return attachment!
    }
    return nil

}
于 2018-03-05T09:39:54.083 回答