You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS挂起状态下,如何用Objective-C实现推送触发的后台代码执行?

解决iOS挂起状态下通过推送触发后台抓取的问题

我来帮你排查这个问题——这在iOS后台任务开发里是个很常见的坑,咱们一步步来梳理:

1. 先确认后台模式配置是否正确

你必须同时开启两个后台能力,缺一个都不行:

  • 打开Xcode,进入项目的「Signing & Capabilities」标签,找到「Background Modes」
  • 勾选「Background fetch」和「Remote notifications」两项
  • 或者直接在Info.plist里添加UIBackgroundModes数组,包含fetchremote-notification两个字符串

这是基础中的基础,很多人会漏掉其中一项导致触发失败。

2. 推送Payload必须包含content-available: 1

这是最容易踩的坑!推送的JSON里必须把content-available作为顶级字段(不能放在aps字典里),示例如下:

{
  "aps": {
    "alert": "你的通知内容",
    "sound": "default"
  },
  "content-available": 1
}

如果是静默推送(不需要显示通知弹窗),aps里可以只保留必要字段,但content-available依然要放在顶级位置:

{
  "aps": {
    "content-available": 1
  }
}

注意:用Xcode的推送模拟器测试可能不会正确触发后台逻辑,建议用APNs官方工具或者第三方推送平台发送测试推送。

3. 确保你的代码实现正确且规范

你已经实现了带fetchCompletionHandlerdidReceiveRemoteNotification方法,但要注意几个关键点:

  • 必须调用completionHandler:系统会根据这个回调判断任务是否完成,超过时限(约30秒)没调用的话,应用会被系统终止
  • 后台任务不能太耗时:只能做轻量级操作,比如数据同步、小请求,复杂操作会被系统杀掉
  • 示例代码参考:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // 这里执行你的后台逻辑,比如更新本地数据、发送统计请求
    NSLog(@"后台收到推送,开始执行任务: %@", userInfo);
    
    // 根据任务结果调用completionHandler
    completionHandler(UIBackgroundFetchResultNewData); // 可选值:NewData/NoData/Failed
}

另外,如果你用了iOS 13+的SceneDelegate,还要在SceneDelegate里实现对应的方法:

- (void)scene:(UIScene *)scene didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // 同样的逻辑处理
    completionHandler(UIBackgroundFetchResultNewData);
}

4. 正确的测试姿势

调试后台任务不能直接在Xcode挂起应用(Xcode附加调试会干扰系统的后台调度),正确步骤:

  1. 将应用安装到真机,断开Xcode连接
  2. 打开应用,按Home键将其挂起
  3. 发送带content-available:1的推送
  4. 重新打开应用,查看日志确认任务是否执行

你也可以用Xcode的「Debug → Simulate Background Fetch」来模拟定时触发的后台抓取,验证你的任务逻辑是否正常。

关于“应用关闭时无响应”的说明

这里要明确:如果用户把应用从多任务栏划掉(完全关闭),iOS会终止应用进程,此时推送无法触发任何后台代码——这是iOS的安全机制,没有办法绕过。只有应用处于后台/挂起状态时,才能触发推送驱动的后台抓取。

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

火山引擎 最新活动