Rewrite `UNNotificationServiceExtension` sub class into Swift 6 async await notation

I'm trying to rewrite a Swift code to Swift 6 language mode and am stuck with this problem. How do I safely pass the bestAttemptContent and contentHandler to the Task? This is from the UNNotificationServiceExtension subclass.

final class NotificationService: UNNotificationServiceExtension {
    
      var contentHandler: ((UNNotificationContent) -> Void)?
      var bestAttemptContent: UNMutableNotificationContent?
      var customNotificationTask: Task<Void, Error>?
    
      override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        guard let bestAttemptContent = bestAttemptContent else {
    
          invokeContentHandler(with: request.content)
          return
        }
    
        do {
          let notificationModel = try PushNotificationUserInfo(data: request.content.userInfo)
          guard let templatedImageUrl = notificationModel.templatedImageUrlString,
                let imageUrl = imageUrl(from: templatedImageUrl) else {
            invokeContentHandler(with: bestAttemptContent)
            return
          }
          setupCustomNotificationTask(
            imageUrl: imageUrl,
            bestAttemptContent: bestAttemptContent,
            contentHandler: contentHandler
          )
        } catch {
          invokeContentHandler(with: bestAttemptContent)
        }
      }
    
      // More code
    
      private func downloadImageTask(
            imageUrl: URL,
            bestAttemptContent: UNMutableNotificationContent,
            contentHandler: @escaping (UNNotificationContent) -> Void
      ) {
            self.customNotificationTask = Task {
              let (location, _) = try await URLSession.shared.download(from: imageUrl)
              let desiredLocation = URL(fileURLWithPath: "\(location.path)\(imageUrl.lastPathComponent)")
              
                try FileManager.default.moveItem(at: location, to: desiredLocation)
                let attachment = try UNNotificationAttachment(identifier: imageUrl.absoluteString, url: desiredLocation, options: nil)
              bestAttemptContent.attachments = [attachment]
              contentHandler(bestAttemptContent)
            }
       }
    }

I tried using the MainActor.run {}, but it just moved the error to that run function. The UNNotificationRequest is not sendable, and I don't think I can make it so. Wrap the setupCustomNotification in a Task will move the errors to the didReceive method. It seems like the consuming keyword will help here, but it leads to a compilation error, even with the latest Xcode (16.2). Any pointers?

I am in the middle of struggling with Swift6 and facing the same compile error, too.

URLSession methods demand @Sendable in their closures.

How about using Kingfisher's downloder?

import Kingfisher
...
let downloader = ImageDownloader.default
downloader.downloadImage(with: url) { result in
    switch result {
    case .success(let value):
       //value.originalData is Data
       ...
        contentHandler(bestAttemptContent)
    case .failure(_):
        contentHandler(bestAttemptContent)
    }
}
...

or using NSData.init?(contentsOf url: URL) (This runs synchronously, not an ideal solution but very simple one)

https://developer.apple.com/documentation/foundation/nsdata/1413892-init

At least, this compile error vanishes with any of these. (Currently we have too many compile errors with Swift6.)

Rewrite `UNNotificationServiceExtension` sub class into Swift 6 async await notation
 
 
Q