You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter iOS富通知问题:添加扩展服务后通知图片不显示

iOS通知无法显示图片的排查与解决步骤

一、先检查Notification Extension的基础配置

  • 打开Extension的Info.plist,确认NSExtension下的NSExtensionAttributes里:UNNotificationExtensionDefaultContentHidden设为NO,UNNotificationExtensionInitialContentSizeRatio设成1.0这类合理值;如果推送里指定了category,要保证UNNotificationExtensionCategory和推送的category完全匹配。
  • 核对Extension的签名:必须和主App用同一个开发者账号,且Extension的target里已经开启Push Notification权限。
  • 确认Extension的Deployment Target不高于主App,且最低版本不低于iOS 10(通知扩展的最低支持版本)。

二、修正Firebase推送负载格式

你当前的负载有个坑:用notification字段时,Firebase可能直接走系统通知通道,不会触发Extension。可以改成下面两种格式之一:

格式一:纯Data推送(推荐,完全由App和Extension处理)

{
    "to" : "__token__",
    "data": {
        "mutable_content": "true",
        "title": "title",
        "body": "body",
        "image": "https://ilyarm.ru/assets/949163b5edd92aa1ec0379734-697x403.jpg"
    }
}

格式二:保留Notification字段,同时在APNS里明确设置mutable-content

{
    "notification": {
        "title": "title",
        "body": "body"
    },
    "apns": {
        "payload": {
            "aps": {
                "mutable-content": 1
            }
        }
    },
    "to" : "__token__",
    "data": {
        "image": "https://ilyarm.ru/assets/949163b5edd92aa1ec0379734-697x403.jpg"
    }
}

三、检查Extension的代码逻辑

确保你的NotificationService里正确实现了图片下载和附件添加逻辑,参考下面的代码:

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 let content = bestAttemptContent,
              let imageUrlStr = content.userInfo["image"] as? String,
              let imageUrl = URL(string: imageUrlStr) else {
            contentHandler(request.content)
            return
        }
        
        // 下载图片并生成通知附件
        URLSession.shared.dataTask(with: imageUrl) { [weak self] data, _, error in
            guard let self = self,
                  let data = data,
                  let image = UIImage(data: data),
                  let attachment = self.saveImageAsAttachment(image: image, name: "notify_img.jpg") else {
                contentHandler(content)
                return
            }
            
            content.attachments = [attachment]
            contentHandler(content)
        }.resume()
    }
    
    override func serviceExtensionTimeWillExpire() {
        // 超时就返回原始内容,避免通知不显示
        if let handler = contentHandler, let content = bestAttemptContent {
            handler(content)
        }
    }
    
    // 私有方法:把图片存到临时目录生成通知附件
    private func saveImageAsAttachment(image: UIImage, name: String) -> UNNotificationAttachment? {
        let tempDir = NSTemporaryDirectory()
        let filePath = tempDir + name
        guard let imageData = image.jpegData(compressionQuality: 0.8) else { return nil }
        
        do {
            try imageData.write(to: URL(fileURLWithPath: filePath))
            return try UNNotificationAttachment(identifier: name, url: URL(fileURLWithPath: filePath), options: nil)
        } catch {
            return nil
        }
    }
}
  • 重点:如果图片下载超时,会触发serviceExtensionTimeWillExpire,所以要保证图片链接访问速度快,或者加个超时处理。

四、调试验证

  • 用Xcode直接运行Extension的target,在didReceive方法里打个断点,看是否能触发;如果没触发,说明推送没走到Extension,回到配置和负载检查。
  • 查看Xcode控制台日志,找Extension相关的错误(比如签名失败、文件写入报错等)。

内容的提问来源于stack exchange,提问作者Aman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:45:58