1

I'm using rich notifications to display a https url image in a push notification. The image is full screen. The problem is the rich notification displays the center of the image which cuts off the top and bottom of the image.

I tried to shrink the image before sending it, but it still gets cut off.

I tried to shrink the image when retrieving it and displaying it but it still gets cut off.

How can I get the entire image to fit inside the rich notification attachment?

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

rich notification with the top and bottom cut off (no head, no bottom foot):

enter image description here

an example of the image before the top and bottom were cut off (has head and feet):

enter image description here

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256

1 Answers1

0

I couldn't get the full image but I could get the top half of it by cropping it using this 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
    }
}

enter image description here

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256