首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有UNNotificationAttachment或远程URL的UIImage

带有UNNotificationAttachment或远程URL的UIImage
EN

Stack Overflow用户
提问于 2016-08-23 13:50:16
回答 4查看 20.5K关注 0票数 21

在我的Notification Service Extension中,我正在从URL下载一个图像,以便在通知中显示为UNNotificationAttachment

因此,我将这个映像作为UIImage,而不需要仅仅为了设置通知就将其写入我的应用程序目录/组容器中。

是否有一种用UNNotificationAttachment ?创建的好方法(应该适用于本地和远程通知)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-23 13:50:16

  1. 在tmp文件夹中创建目录
  2. NSData表示的UIImage写入新创建的目录
  3. 为tmp文件夹中的文件创建带有url的UNNotificationAttachment
  4. 清理tmp文件夹

我在UINotificationAttachment上写了一个扩展

代码语言:javascript
运行
复制
extension UNNotificationAttachment {

    static func create(identifier: String, image: UIImage, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
        let tmpSubFolderURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(tmpSubFolderName, isDirectory: true)
        do {
            try fileManager.createDirectory(at: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)
            let imageFileIdentifier = identifier+".png"
            let fileURL = tmpSubFolderURL.appendingPathComponent(imageFileIdentifier)
            let imageData = UIImage.pngData(image)
            try imageData()?.write(to: fileURL)
            let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL, options: options)
            return imageAttachment
        } catch {
            print("error " + error.localizedDescription)
        }
        return nil
    }
}

因此,要从一个UNUserNotificationRequest中使用UNUserNotificationAttachment创建UIImage,您可以这样做

代码语言:javascript
运行
复制
let identifier = ProcessInfo.processInfo.globallyUniqueString
let content = UNMutableNotificationContent()
content.title = "Hello"
content.body = "World"
if let attachment = UNNotificationAttachment.create(identifier: identifier, image: myImage, options: nil) {
    // where myImage is any UIImage
    content.attachments = [attachment] 
}
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 120.0, repeats: false)
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
    // handle error
}

这应该是可行的,因为UNNotificationAttachment会将图像文件复制到自己的位置。

票数 44
EN

Stack Overflow用户

发布于 2016-09-01 08:51:20

我写了一篇关于这个主题的博客,集中在GIF图片上。但是,应该很容易为简单的图像重写我的代码。

您需要创建一个Notification扩展:

并包括以下代码:

代码语言:javascript
运行
复制
final class NotificationService: UNNotificationServiceExtension {

    private var contentHandler: ((UNNotificationContent) -> Void)?
    private var bestAttemptContent: UNMutableNotificationContent?

    override internal func didReceiveNotificationRequest(request: UNNotificationRequest, withContentHandler contentHandler: (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 attachmentURL = content.userInfo["attachment-url"] as? String else {
            return failEarly()
        }

        guard let imageData = NSData(contentsOfURL:NSURL(string: attachmentURL)!) else { return failEarly() }
        guard let attachment = UNNotificationAttachment.create("image.gif", data: imageData, options: nil) else { return failEarly() }

        content.attachments = [attachment]
        contentHandler(content.copy() as! UNNotificationContent)
    }

    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)
        }
    }

}

extension UNNotificationAttachment {

    /// Save the image to disk
    static func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = NSFileManager.defaultManager()
        let tmpSubFolderName = NSProcessInfo.processInfo().globallyUniqueString
        let tmpSubFolderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(tmpSubFolderName, isDirectory: true)

        do {
            try fileManager.createDirectoryAtURL(tmpSubFolderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = tmpSubFolderURL?.URLByAppendingPathComponent(imageFileIdentifier)
            try data.writeToURL(fileURL!, options: [])
            let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, URL: fileURL!, options: options)
            return imageAttachment
        } catch let error {
            print("error \(error)")
        }

        return nil
    }
}

有关更多信息,您可以在这里查看我的博客:http://www.avanderlee.com/ios-10/rich-notifications-ios-10/

票数 6
EN

Stack Overflow用户

发布于 2020-03-05 13:42:11

下面是一个完整的示例,如何从internet下载图像并将其附加到本地通知(这是原始问题的一部分)。

代码语言:javascript
运行
复制
let content = UNMutableNotificationContent()
content.title = "This is a test"
content.body = "Just checking the walls"

if let url = URL(string: "https://example.com/images/example.png") {

    let pathExtension = url.pathExtension

    let task = URLSession.shared.downloadTask(with: url) { (result, response, error) in
        if let result = result {

            let identifier = ProcessInfo.processInfo.globallyUniqueString                
            let target = FileManager.default.temporaryDirectory.appendingPathComponent(identifier).appendingPathExtension(pathExtension)

            do {
                try FileManager.default.moveItem(at: result, to: target)

                let attachment = try UNNotificationAttachment(identifier: identifier, url: target, options: nil)
                content.attachments.append(attachment)

                let notification = UNNotificationRequest(identifier: Date().description, content: content, trigger: trigger)
                UNUserNotificationCenter.current().add(notification, withCompletionHandler: { (error) in
                    if let error = error {
                        print(error.localizedDescription)
                    }
                })
            }
            catch {
                print(error.localizedDescription)
            }
        }
    }
    task.resume()
}

通常,当下载的文件已经是有效的映像时,不需要重新创建映像。只需将下载的文件复制到具有唯一名称和.png.jpg扩展名的当前临时目录。在现有的临时目录中创建子目录也是不必要的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39103095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档