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

iOS后台推送在App未运行/挂起状态下失效问题排查

后台推送在App未运行/挂起时失效问题排查

已完成配置

  • 项目能力配置:添加Push Notifications能力,开启Background modes中的Remote Notifications选项
  • APNS注册与回调实现(代码位于AppDelegate.swift):
    static let sApp: UIApplication = UIApplication.shared
        
    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            
        // 注册APNS获取设备令牌
        RegisterForRemoteNotifications()
            
        return true;
    }
    func RegisterForRemoteNotifications() {
        
        AppDelegate.sApp.registerForRemoteNotifications()
    }
        
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
            
        Log(String(format: "error.localizedDescription = %@", error.localizedDescription))
    }
        
    // Log(_:) 为自定义日志方法
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken pDeviceToken: Data) {
            
        // 打印设备令牌字符串
        Log("pDeviceToken = " + pDeviceToken.hexEncodedString())
    }
        
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // 后台推送处理逻辑
        ....
    }
    

测试推送命令

使用curl发送后台推送请求:

curl -v --header "apns-push-type:background" --header "apns-priority:5" --header "apns-topic: $TOPIC" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps":{"content-available":1},"Purpose":"Background update"}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}

问题现象

  • App处于前台时,后台推送可正常接收,application(_:didReceiveRemoteNotification:fetchCompletionHandler:)方法正常触发
  • App未运行/挂起时,推送无法即时唤醒App执行后台逻辑,直到将App切换至前台才会收到推送

环境信息:iOS 16.0(真机)、Xcode 14.2、设备电量100%(连接Mac)

Update1:后续偶现现象

发布问题几天后,后台通知偶尔能唤醒App(约3次中有1次),对应的启动日志流程:

application(:willFinishLaunchingWithOptions:)
...
RequestUserPermission() // 请求通知权限(与当前问题无关)
RegisterForRemoteNotifications() // 注册APNS
application(
:didFinishLaunchingWithOptions:)
...
CreateMainWindow()
...
application(:didRegisterForRemoteNotificationsWithDeviceToken:) // APNS注册成功
...
applicationDidBecomeActive(
:)
applicationWillResignActive(:)
applicationDidEnterBackground(
:)
...
applicationwillTerminate(:) // 从后台划掉App
// 后台通知触发新启动
application(
:willFinishLaunchingWithOptions:)
RequestUserPermission()
RegisterForRemoteNotifications()
application(:didFinishLaunchingWithOptions:)
CreateMainWindow()
application(
:didReceiveRemoteNotification:fetchCompletionHandler:)
...
application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
...

排查方向与解决方案建议

  1. 推送负载与请求头校验

    • 确保aps字典中content-available字段值严格为1,且负载不包含alert、sound等会触发用户通知的字段(后台推送为静默更新,不应展示通知)
    • 确认apns-push-type固定为background,apns-priority固定为5(后台推送必须使用低优先级,否则会被系统拦截)
  2. 调试环境影响消除

    • 断开设备与Mac的连接,脱离Xcode调试状态测试:调试会话会干扰系统的后台唤醒逻辑,即使电量100%也可能限制App后台活动
    • 降低推送测试频率:iOS 16+对后台唤醒有严格节流,高频推送会被系统抑制,建议间隔5-10分钟测试一次
  3. 启动流程适配

    • 在application(_:didFinishLaunchingWithOptions:)中检查launchOptions是否包含UIApplication.LaunchOptionsKey.remoteNotification,如果存在则说明是后台推送唤醒的启动,需确保此时核心服务已初始化完成,避免依赖未就绪导致处理逻辑失效
    • 务必在后台任务完成后调用fetchCompletionHandler,并返回对应UIBackgroundFetchResult(.newData/.noData/.failed),未及时调用会导致系统减少后续后台唤醒机会
  4. 设备设置检查

    • 确认设备未开启“低电量模式”(即使当前电量100%,历史开启状态可能有遗留影响)
    • 检查App的“后台App刷新”权限是否开启(设置→通用→后台App刷新→对应App)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:20:35