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

iOS端Flutter CallKit切换其他应用后后台/终止状态收不到通知

iOS Flutter CallKit Incoming 后台/终止状态切应用后无法接收通知的排查与解决

问题描述

我的iOS应用使用Flutter CallKit Incoming插件时,原本前台、后台、终止状态下都能正常接收CallKit通话通知,但存在以下异常场景:

  • 当应用处于后台或终止状态时,关闭/最小化我的应用后打开其他应用,后续在后台/终止状态下无法再接收CallKit通知。
  • Android端无此问题,一切正常。

云函数发送静默通知代码

await admin.messaging().send({
  token: token_o,
  notification: {},
  data: {
    imageUrl: requesterImageUrl,
    chatRoomId: chatRoomId,
    screenName: 'voiceScreen',
    voiceCall: 'voiceCall',
    callerName: requesterName,
    callsDocId: callsDocId,
    senderId: requesterId,
  },
  android: {
      notification: {
          click_action: "android.intent.action.MAIN"
      },
  },
   apns: {
            headers: {
              apns_priority: "10",
            },
            payload: {
              aps: {
                badge: 1
              },
              notification: {
              title: "iOVoiceCallNotification",
              body: {},
                                },
              mutable_content: true,
              content_available : true,

            }
          }
}).then(value => {
  functions.logger.log("Notification for AudioCall is sent to the Receiver");
}).catch((e) => {
  functions.logger.log(e.toString());
});

排查与解决步骤

1. 修正APNs通知配置

你的APNs payload存在结构错误,这是导致iOS推送异常的核心原因之一:

  • 调整payload结构:notification字段不应放在payload根目录,需合并到aps的alert节点中,且body必须是字符串(不能是空对象);自定义业务数据要放在payload根目录(与aps同级)。
  • 添加apns_topic:必须指定apns_topic为你的App Bundle ID,确保通知定向到正确应用。
    修正后的APNs配置示例:
apns: {
  headers: {
    apns_priority: "10",
    apns_topic: "com.yourapp.bundleid" // 替换为你的实际Bundle ID
  },
  payload: {
    aps: {
      badge: 1,
      content_available: true,
      mutable_content: true,
      alert: {
        title: "iOVoiceCallNotification",
        body: "有来电提醒" // 改为非空字符串
      }
    },
    // 自定义业务数据移到此处
    imageUrl: requesterImageUrl,
    chatRoomId: chatRoomId,
    screenName: 'voiceScreen',
    voiceCall: 'voiceCall',
    callerName: requesterName,
    callsDocId: callsDocId,
    senderId: requesterId,
  }
}
  • 规范字段拼写:content_available : true中的空格建议去掉,保持语法严谨。

2. 确认iOS后台权限配置

  • 开启VoIP后台模式:在Xcode中进入项目Signing & Capabilities,添加Background Modes并勾选Voice over IP,同时确保Push Notifications权限已开启。
  • 检查系统级权限:引导用户检查系统设置:设置 > 你的应用 > 通知,确保允许通知、在锁定屏幕上显示开启;设置 > 通用 > 后台App刷新,开启你的应用权限。
  • 验证VoIP证书:确认APNs的VoIP推送证书有效且未过期,云函数使用的是对应环境(开发/生产)的证书(VoIP证书与普通推送证书不通用)。

3. 检查Flutter端CallKit初始化逻辑

  • 确保启动时初始化:在应用启动(包括终止状态被推送唤醒时),必须正确初始化CallKit并监听事件:
void initState() {
  super.initState();
  _initCallKit();
}

void _initCallKit() async {
  await FlutterCallkitIncoming.init(
    appName: '你的应用名称',
    iconName: 'ic_launcher',
  );
  // 监听CallKit事件
  FlutterCallkitIncoming.onEvent.listen((event) {
    if (event.event == EventAction.ACTION_CALL_INCOMING) {
      // 处理来电逻辑
    }
  });
}
  • 重新注册推送令牌:当应用从后台回到前台,或被其他应用切换后,重新获取并上传VoIP推送令牌到服务器,避免令牌失效导致推送无法送达。

4. 排查iOS系统限制

  • 后台资源限制:iOS在低电量、内存紧张时会主动挂起后台应用,可测试关闭其他后台应用、关闭低电量模式,验证是否恢复正常。
  • 专注模式拦截:检查iOS是否开启了专注模式,该模式可能拦截应用通知,需确保你的应用在专注模式下允许通知。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:24:37