Swift -Rich Notification 截断图像的顶部和底部

Posted

技术标签:

【中文标题】Swift -Rich Notification 截断图像的顶部和底部【英文标题】:Swift -Rich Notification Cuts Off Top and Bottom of Image 【发布时间】:2021-02-21 21:07:03 【问题描述】:

我正在使用丰富的通知在推送通知中显示 https 网址图像。图像是全屏的。问题是富通知显示图像的中心,从而切断了图像的顶部和底部。

我在发送之前尝试缩小图像,但它仍然被截断。

我在检索和显示图像时尝试缩小图像,但它仍然被截断。

如何让整个图像适合丰富的通知附件?

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 bestAttemptContent = bestAttemptContent else  failEarly(); return 
    guard let attachmentUrlString = request.content.userInfo["media-url"] as? String else  failEarly(): return 
    guard let url = URL(string: attachmentUrlString) else  failEarly(); return 
    
    URLSession.shared.downloadTask(with: url, completionHandler:  [weak self](tempLocation, response, error) -> Void in
        
        if let error = error  return 
        guard let location = tempLocation else  return 
        guard let response = response else  return 
        
        do 
            let lastPathComponent = response.url?.lastPathComponent ?? ""
            var attachmentID = UUID.init().uuidString + lastPathComponent
            
            if response.suggestedFilename != nil 
                attachmentID = UUID.init().uuidString + response.suggestedFilename!
            
            
            let tempDict = NSTemporaryDirectory()
            let tempFilePath = tempDict + attachmentID
            
            try FileManager.default.moveItem(atPath: location.path, toPath: tempFilePath)

            guard let image = UIImage(contentsOfFile: tempFilePath) else  return 
            guard let resizedImage = NotificationService.resizeImage(image: image, newWidth: 200) else  return  // I went all the way down to 25 and it was just a blurry image
            guard let imageData = resizedImage.jpegData(compressionQuality: 1.0) else  return 
            let fileURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
                .appendingPathComponent("pkm", isDirectory: false)
                .appendingPathExtension("jpg")
            try imageData.write(to: fileURL)
            let attachment = try UNNotificationAttachment.init(identifier: "pkm.jpg", url: fileURL, options: nil)
            
            bestAttemptContent.attachments.append(attachment)
        
        catch  return 
        
        OperationQueue.main.addOperation([weak self]() -> Void in
            self?.contentHandler?(bestAttemptContent);
        )
    ).resume()


extension NotificationService 

    static func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? 
        let scale = newWidth / image.size.width
        let newHeight = image.size.height * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    

顶部和底部截断的丰富通知(无头,无底脚):

顶部和底部被切断之前的图像示例(有头和脚):

【问题讨论】:

【参考方案1】:

我无法获得完整的图像,但我可以通过使用 answer 裁剪它来获得它的上半部分

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 bestAttemptContent = bestAttemptContent else  failEarly(); return 
    guard let attachmentUrlString = request.content.userInfo["media-url"] as? String else  failEarly(): return 
    guard let url = URL(string: attachmentUrlString) else  failEarly(); return 
    
    URLSession.shared.downloadTask(with: url, completionHandler:  [weak self](tempLocation, response, error) -> Void in
        
        if let error = error  return 
        guard let location = tempLocation else  return 
        guard let response = response else  return 
        
        do 
            let lastPathComponent = response.url?.lastPathComponent ?? ""
            var attachmentID = UUID.init().uuidString + lastPathComponent
            
            if response.suggestedFilename != nil 
                attachmentID = UUID.init().uuidString + response.suggestedFilename!
            
            
            let tempDict = NSTemporaryDirectory()
            let tempFilePath = tempDict + attachmentID
            
            try FileManager.default.moveItem(atPath: location.path, toPath: tempFilePath)
            guard let image = UIImage(contentsOfFile: tempFilePath) else  return 

            let croppedImage = NotificationService.cropImageInHalf(image: image) // cropping occurs here
            
            guard let imageData = croppedImage.jpegData(compressionQuality: 1.0) else  return 

            let fileURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
                .appendingPathComponent("pkm", isDirectory: false)
                .appendingPathExtension("jpg")
            try imageData.write(to: fileURL)
            let attachment = try UNNotificationAttachment.init(identifier: "pkm.jpg", url: fileURL, options: nil)
            
            bestAttemptContent.attachments.append(attachment)
        
        catch  return 
        
        OperationQueue.main.addOperation([weak self]() -> Void in
            self?.contentHandler?(bestAttemptContent);
        )
    ).resume()


extension NotificationService 

    static func cropImageInHalf(image: UIImage) -> UIImage 
        let height = CGFloat(image.size.height * 0.5)
        let rect = CGRect(x: 0, y: 0, width: image.size.width, height: height)
        return cropImage(image: image, toRect: rect)
    

    static func cropImage(image:UIImage, toRect rect:CGRect) -> UIImage 
        let imageRef:CGImage = image.cgImage!.cropping(to: rect)!
        let croppedImage:UIImage = UIImage(cgImage:imageRef)
        return croppedImage
    

【讨论】:

以上是关于Swift -Rich Notification 截断图像的顶部和底部的主要内容,如果未能解决你的问题,请参考以下文章

Swift导航到View from notification

swift_通知的使用

Swift 到 Swift 2 [重复]

Notification的简单使用

Swift 本地推送通知UILocalNotification

用UILocalNotification实现一个闹钟(Swift)