iOS/FCM:如何用Payload图片名展示XCAsset中的通知附件图
Hey there! Let's walk through how to use the image name from your FCM payload to pull images from your XCAsset folder and show them as notification attachments. Here's what you need to do:
1. Update Your FCM Payload to Include the Image Name
First, add an image_name field under the data section of your payload. The data field lets us pass custom data to your app, which we'll use to fetch the right image from XCAssets. Here's your updated payload:
{ "to": "/topics/03772", "content_available": true, "mutable_content": true, "priority": "high", "notification": { "title": "Daily forecast", "body": "Blue sky, no clouds", "sound": "default" }, "data": { "image_name": "sunny_sky" // Match this exactly to your XCAsset image name } }
Note: Don't put custom data in the notification section — that's only for system-handled content like title/body.
2. Use a Notification Service Extension
To modify the incoming notification and add attachments, you need a Notification Service Extension in your iOS project. If you don't have one yet:
- Go to Xcode > File > New > Target
- Select "Notification Service Extension" and follow the setup prompts.
3. Code the Attachment Logic in the Extension
Open the NotificationService.swift file in your extension and replace the default code with this:
import UserNotifications import UIKit 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) // Guard against missing content or image name guard let content = bestAttemptContent, let dataDict = content.userInfo["data"] as? [String: Any], let imageName = dataDict["image_name"] as? String, let image = UIImage(named: imageName, in: Bundle.main, compatibleWith: nil) else { // Fallback to original notification if anything fails contentHandler(request.content) return } // Convert image to a temporary file (required for notification attachments) guard let imageData = image.pngData(), let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(imageName).png") else { contentHandler(content) return } do { // Write image data to temp file try imageData.write(to: tempFileURL) // Create notification attachment let attachment = try UNNotificationAttachment(identifier: imageName, url: tempFileURL, options: nil) // Attach to the notification content content.attachments = [attachment] // Deliver the modified notification contentHandler(content) } catch { print("Failed to create attachment: \(error.localizedDescription)") contentHandler(content) } } override func serviceExtensionTimeWillExpire() { // If we run out of time, deliver the best attempt content if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
4. Key Things to Check
- XCAsset Image Target Membership: Make sure your image in XCAssets is included in both your main app target and the Notification Service Extension target. You can verify this by selecting the image in Xcode, then checking the "Target Membership" section in the right sidebar.
- Case Sensitivity: iOS file names are case-sensitive — ensure the
image_namein your payload matches the exact case of your XCAsset image name. - Image Format: If you're using JPEG images instead of PNG, replace
image.pngData()withimage.jpegData(compressionQuality: 0.8)and update the temp file extension to.jpeg. - Size Limits: Notification attachments have size limits (usually ~10MB on iOS), so keep your images optimized.
内容的提问来源于stack exchange,提问作者user7219266

