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

iOS自定义推送通知(Notification Service Extension)部署问题咨询

自定义推送通知(带图片)问题解决指南

核心问题解答

是的,你必须为Notification Service Extension创建独立的Bundle ID和对应的配置文件。主应用与扩展的Bundle ID必须唯一,这正是你安装时出现having same bundle id in app and extension报错的直接原因。

具体操作步骤

1. 创建独立Bundle ID

  • 登录Apple开发者后台,进入「Certificates, Identifiers & Profiles」
  • 点击「Identifiers」→ 「+」新建标识符
  • 选择「App IDs」分类下的「Notification Service Extension」类型(或直接选「App ID」,类型指定为「Extension」)
  • 填写独立的Bundle ID,推荐格式为主应用Bundle ID加后缀,比如主应用是com.yourapp.main,扩展可设为com.yourapp.main.NotificationService
  • 勾选「Push Notifications」和「App Groups」(若需要主应用与扩展共享数据),完成创建

2. 生成对应配置文件

  • 在开发者后台「Profiles」页面,点击「+」新建配置文件
  • 选择「iOS App Development」(或对应发布环境的配置类型),点击下一步
  • 选中刚创建的扩展Bundle ID,关联对应的开发证书和测试设备,完成配置文件生成并下载

3. 配置Xcode扩展目标

  • 在Xcode中选中Notification Service Extension目标,进入「Signing & Capabilities」面板
  • 填入刚才创建的独立Bundle ID,导入下载的配置文件(或开启「Automatically manage signing」,确保Xcode自动匹配正确的Bundle ID与配置文件)

通知服务类的触发逻辑

Notification Service Extension的核心类NotificationService无需你主动调用,系统会自动触发其方法:当收到包含mutable-content: 1字段的推送时,系统会自动调用didReceive(_:withContentHandler:)方法处理通知内容。

示例代码实现

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
        
        // 从推送payload中提取图片URL并处理
        guard let content = bestAttemptContent,
              let imageURLStr = content.userInfo["image_url"] as? String,
              let imageURL = URL(string: imageURLStr) else {
            contentHandler(content ?? request.content)
            return
        }
        
        // 下载图片并生成通知附件
        URLSession.shared.dataTask(with: imageURL) { [weak self] data, _, error in
            guard let self = self, let data = data, error == nil else {
                contentHandler(content)
                return
            }
            
            let tempPath = NSTemporaryDirectory() + "notification_image.jpg"
            let tempURL = URL(fileURLWithPath: tempPath)
            
            do {
                try data.write(to: tempURL)
                let attachment = try UNNotificationAttachment(identifier: "image_attachment", url: tempURL, options: nil)
                content.attachments = [attachment]
                contentHandler(content)
            } catch {
                contentHandler(content)
            }
        }.resume()
    }

    override func serviceExtensionTimeWillExpire() {
        // 处理超时场景,返回原始通知内容
        if let handler = contentHandler, let content = bestAttemptContent {
            handler(content)
        }
    }
}

推送Payload要求

推送必须包含mutable-content: 1字段,否则系统不会触发扩展处理,示例Payload如下:

{
    "aps": {
        "alert": {
            "title": "自定义通知",
            "body": "这是一张带图片的通知"
        },
        "mutable-content": 1,
        "sound": "default"
    },
    "image_url": "https://example.com/your-notification-image.jpg"
}

验证步骤

  1. 确认主应用与扩展的App Groups配置完全一致(若使用共享数据)
  2. 重新打包安装应用,确认Bundle ID冲突报错消失
  3. 发送符合要求的测试推送,检查通知是否正常显示图片

内容的提问来源于stack exchange,提问作者Amit Kumar SIngh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:25:21