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

iOS通知服务扩展无法加载富推送图片问题咨询

解决Notification Service Extension图片不显示的问题

嘿,我之前正好踩过这个坑——你的payload配置是对的(已经加了mutable-content: 1和图片链接),但确实需要在Notification Service Extension里编写额外代码,因为Extension默认的模板只是个空壳,不会自动帮你下载并附加图片到通知里。

下面是具体的解决步骤和代码示例:

1. 先确认Extension的基础配置

首先确保你的Notification Service Extension满足这些条件:

  • 和主APP使用相同的签名配置(开发/生产配置文件)
  • Deployment Target和主APP保持一致
  • 已经开启了App Group(这个很重要,因为Extension和主APP沙盒隔离,需要通过App Group共享附件文件)

2. 编写Extension的核心处理代码

打开NotificationService.swift,替换默认代码为以下逻辑——主要是下载图片、将图片保存到共享沙盒、然后添加为通知附件:

import UserNotifications

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 attachmentURLString = content.userInfo["attachment-url"] as? String,
              let imageURL = URL(string: attachmentURLString) else {
            // 如果获取失败,直接返回原始通知内容
            contentHandler(request.content)
            return
        }
        
        // 下载图片文件
        URLSession.shared.downloadTask(with: imageURL) { [weak self] tempFileURL, _, error in
            guard let self = self,
                  let tempURL = tempFileURL, error == nil else {
                contentHandler(content)
                return
            }
            
            // 将临时文件移动到App Group共享目录(避免Extension销毁后文件被删除)
            let fileManager = FileManager.default
            guard let groupDirectory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "你的App Group ID") else {
                contentHandler(content)
                return
            }
            
            let cacheDirectory = groupDirectory.appendingPathComponent("Library/Caches/Notifications")
            do {
                // 创建缓存目录(如果不存在)
                try fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true)
                // 生成唯一文件名,避免冲突
                let attachmentFileName = "\(UUID().uuidString).jpg"
                let attachmentURL = cacheDirectory.appendingPathComponent(attachmentFileName)
                
                // 移动临时文件到目标路径
                try fileManager.moveItem(at: tempURL, to: attachmentURL)
                
                // 创建通知附件并添加到内容中
                let attachment = try UNNotificationAttachment(identifier: "image_attachment", url: attachmentURL, options: nil)
                content.attachments = [attachment]
                
                // 返回处理后的通知内容
                self.contentHandler?(content)
            } catch {
                print("处理通知附件出错: \(error.localizedDescription)")
                // 出错时返回原始内容
                contentHandler(content)
            }
        }.resume()
    }
    
    override func serviceExtensionTimeWillExpire() {
        // 当Extension运行超时(约30秒),返回当前已处理的内容
        if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

3. 关键注意事项

  • App Group配置:一定要在主APP和Extension的Target -> Signing & Capabilities里添加同一个App Group ID,代码里的"你的App Group ID"要替换成你实际的ID(比如group.com.yourapp.notifications)。
  • 图片格式与链接:确保图片链接是可访问的HTTPS链接(iOS通知附件不支持HTTP),且格式是iOS支持的(jpg、png、gif等,你的jpg没问题)。
  • 超时处理:Extension的运行时间有限,如果图片下载超时,serviceExtensionTimeWillExpire()会被触发,这时候要返回原始内容,避免通知完全不显示。
  • Payload检查:确认mutable-content是数字1(不是字符串"1"),你的payload里已经是对的,这是系统调用Extension的开关。

按照上面的步骤配置后,再用Pusher测试,应该就能在通知中心看到带图片的富推送了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:17:39