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

App后台自定义长通知音效随通知徽章消失中断的解决咨询

解决iOS后台通知长音效被截断问题

核心原因

系统默认通知的音效播放会和通知展示生命周期绑定,当通知徽章/横幅消失后,音效会被强制停止。要播放完整的长音效,必须通过UNNotificationServiceExtension接管通知处理逻辑,脱离系统默认的音效播放限制。


具体解决方案

1. 添加Notification Service Extension

  • 在Xcode中选择File > New > Target,找到Notification Service Extension,创建后激活该target。
  • 确保Extension的部署目标和主App一致。

2. 配置Extension的音频权限

在Extension的Info.plist中添加UIBackgroundModes数组,包含audio项,允许Extension在后台播放音频:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>

3. 在Extension中手动播放长音效

替换Extension默认的didReceive(_:withContentHandler:)方法,使用AVAudioPlayer播放自定义音效,示例代码(Swift):

import UserNotifications
import AVFoundation

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?
    var audioPlayer: AVAudioPlayer?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
        
        guard let content = bestAttemptContent else {
            contentHandler(request.content)
            return
        }
        
        // 加载并播放自定义长音效
        if let soundURL = Bundle.main.url(forResource: "your_custom_sound", withExtension: "mp3") {
            do {
                try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
                try AVAudioSession.sharedInstance().activate()
                audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
                audioPlayer?.play()
            } catch {
                print("音效播放失败: \(error.localizedDescription)")
            }
        }
        
        // 传递处理后的通知内容
        contentHandler(content)
    }

    override func serviceExtensionTimeWillExpire() {
        // 确保Extension过期前完成内容处理
        if let handler = contentHandler, let content = bestAttemptContent {
            handler(content)
        }
    }
}

4. 确保通知触发Extension处理

  • 本地通知:创建时设置content.mutableContent = true,示例:
    let content = UNMutableNotificationContent()
    content.mutableContent = true
    // 其他通知配置...
    
  • 远程通知:在payload中添加mutable-content: 1,示例:
    {
        "aps": {
            "alert": "您的通知内容",
            "mutable-content": 1
        }
    }
    

5. 音效文件部署

将自定义音效文件同时添加到主App和Notification Service Extension的target中,确保两者的Bundle都能访问到该文件。


内容的提问来源于stack exchange,提问作者S.S.D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:25:49