iOS Swift下VoIP来电未接听/被叫终止的正确处理方案咨询
iOS VoIP通知与CallKit通话终止处理方案
一、未接听/主叫主动终止时的VoIP上报合规问题
iOS 13+要求所有VoIP通知必须关联真实的来电场景,绝对不能在无需展示来电的场景下发VoIP通知(比如超时未接听后发取消通知、主叫主动终止时发通知),这类操作会触发苹果政策检测,导致后续VoIP推送权限被限制。正确做法是:
- 仅在需要发起真实来电提醒时发送VoIP通知;
- 超时未接听或主叫终止的场景,直接通过CallKit自身API结束通话并移除通知,无需额外发送VoIP通知。
二、让APP知晓通话终止的方式
不管通话是否被接听,可通过以下几种可靠方式感知状态:
- CallKit代理回调:实现
CXProviderDelegate的核心方法:provider:performEndCallAction::用户主动挂断、系统触发结束时回调;provider:timedOutPerformingAction::CallKit动作超时(比如30秒未接听)时触发;provider:didDeactivateAudioSession::通话音频会话关闭,说明通话已终止。
- 服务器普通APNs通知:主叫端终止通话时,服务器给被叫APP发送普通APNs通知(非VoIP),APP收到后调用CallKit结束会话的API。
- 本地定时器触发:展示CallKit来电界面后启动本地30秒定时器,超时后主动调用CallKit结束通话的API。
三、上报VoIP但不唤起CallKit界面并自动终止的方法
不存在这种合规操作——VoIP通知的设计初衷就是触发来电提醒,只要通过pushRegistry:didReceiveIncomingPushWithPayload:forType:completion:处理并调用reportNewIncomingCall上报VoIP通知,就必须展示CallKit来电界面,否则属于违规。如果不需要唤起来电界面,一开始就不应使用VoIP通知,改用普通APNs通知同步状态即可。
补充主叫主动终止的标准流程:
- 主叫端通知服务器通话终止;
- 服务器给被叫APP发送普通APNs通知;
- 被叫APP收到通知后,检查是否有活跃的CallKit通话请求,若有则调用
CXEndCallAction结束通话并移除来电通知。
内容的提问来源于stack exchange,提问作者user18084770
相关产品推荐
相关产品推荐

