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

Xcode14 & iOS16中VOIP流崩溃:需改用Local Push Connectivity

问题:iOS 16下设置VOIP类型Socket流导致APP启动崩溃

环境与崩溃现象

在Xcode 14 & iOS 16环境下,APP启动后立即崩溃,排查后确定崩溃发生在调用inputStream!.open()和outputStream!.open()打开流的环节。

相关代码

流定义

private var inputStream: InputStream!
private var outputStream: OutputStream!

流创建代码

var readStream:  Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?

CFStreamCreatePairWithSocketToHost(nil, connectionConfiguration.host, connectionConfiguration.port, &readStream, &writeStream)

inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()

inputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: .socketSecurityLevelKey)
outputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL, forKey: .socketSecurityLevelKey)

inputStream.setProperty(StreamNetworkServiceTypeValue.voIP, forKey: Stream.PropertyKey.networkServiceType)
outputStream.setProperty(StreamNetworkServiceTypeValue.voIP, forKey: Stream.PropertyKey.networkServiceType)

流配置代码

inputStream!.delegate = self
outputStream!.delegate = self
inputStream!.schedule(in: .main, forMode: RunLoop.Mode.default)
outputStream!.schedule(in: .main, forMode: RunLoop.Mode.default)

崩溃触发代码

inputStream!.open()
outputStream!.open()

崩溃日志

libsp.dylib`spd_checkin_socket.cold.1:
    0x21c764464 <+0>:  adrp   x8, 144598
    0x21c764468 <+4>:  adrp   x9, 0
    0x21c76446c <+8>:  add    x9, x9, #0xa3f            ; "Linked against modern SDK, VOIP socket will not wake. Use Local Push Connectivity instead"
    0x21c764470 <+12>: str    x9, [x8, #0x390]
->  0x21c764474 <+16>: brk    #0x1

问题原因

iOS 16及后续版本中,苹果彻底废弃了通过设置networkServiceType为.voIP来创建VOIP类型Socket的方式,系统会直接触发崩溃,强制开发者使用Local Push Connectivity框架实现需要后台唤醒的网络连接需求。

解决方案

1. 移除VOIP类型设置(立即修复崩溃)

删除流创建代码中设置networkServiceType为.voIP的两行代码:

// 移除以下两行代码
// inputStream.setProperty(StreamNetworkServiceTypeValue.voIP, forKey: Stream.PropertyKey.networkServiceType)
// outputStream.setProperty(StreamNetworkServiceTypeValue.voIP, forKey: Stream.PropertyKey.networkServiceType)

如果你的业务仅需要前台Socket连接,不需要后台唤醒,这一步即可解决崩溃问题,Socket能正常建立。

2. 改用Local Push Connectivity实现后台连接(针对需要后台唤醒的场景)

若需APP在后台保持网络连接并被唤醒,需使用苹果官方的Local Push Connectivity方案:

  • 向项目中添加PushKit框架
  • 实现PKPushRegistry注册VOIP类型推送,通过推送事件唤醒APP后再建立Socket连接
  • 建立Socket时,使用默认的networkServiceType或根据业务选择.default等合适类型,不再设置.voIP

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:07:38