我报名参与金石方案1期应战——分割10万奖池,这是我的第2篇文章,点击查看活动详情

本篇文章记录了从昨日更新iOS16发现的一个溃散问题到处理的过程。

前语

昨日中秋节后第一天上班,苹果爸爸推送了iOS16体系。

所以,作为iOS开发者的惯例操作,我开端漫长晋级之路:

  • 晋级macOS到12.6
  • 晋级iOS16
  • 晋级Xcode14

运转App,然后溃散了,溃散的截图信息如下:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

简略复现溃散状况

由于Xcode14是后续持续开发刚需的IDE版别(理论上说目前运用Xcode13也能够持续进行开发,但是对于适配iOS16,仍是Xcode14更好),咱们对溃散问题进行了简略的复现计算:

IDE版别 iOS版别 设备 是否溃散
Xcode14 iOS 15 真机
Xcode14 iOS 15 模拟器
Xcode14 iOS 16 真机
Xcode14 iOS 16 模拟器

能够看出,该溃散仅仅只在iOS16的真机上呈现。

排查定位问题

依据信息,咱们能够发现溃散的问题呈现在CocoaMQTT相关的依靠库——CocoaAsyncSocket

所以咱们先去CocoaMQTT上面去看了一些open issue:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

有一个8月15日提交的反应的issue,大概是说在Xcode14的beta5上有溃散,并且也是触及CocoaAsyncSocket

所以乎,咱们顺藤摸瓜持续去依靠库CocoaAsyncSocket上面去找找。

公然,一个issue非常夺目:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

I think this is a problem inside iOS 16 Core Foundation framework. The source code of new Core Foundation is not released, so I just file a bug to apple(FB11489606).

依据反应者的定见:以为这个bug可能是由于iOS16架包中的Core Foundation framework导致。

所以咱们又顺带看了看CocoaAsyncSocket的PR:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

第一个PR就格外夺目!处理iOS16在后台的溃散问题。

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

尽管这个PR还没有合并,但是对于咱们App开端连接MQTT就溃散的状况仍是值得试一试的,所以咱们立即在Pod的源码中对这里进行了修正。

修正后,MQTT正常工作,也没有溃散了。

莫非你觉得到这里现已完了?并没有,咱们接着往下看。

深化:kCFStreamNetworkServiceTypeVoIP过期导致的溃散

我特地去看了一下有关kCFStreamNetworkServiceTypeVoIP的代码,其介绍如下:

/* deprecated network service type: */
CFN_EXPORT const CFStringRef kCFStreamNetworkServiceTypeVoIP    CF_DEPRECATED(10_7, 10_11, 4_0, 9_0, "use PushKit for VoIP control purposes");  // voice over IP control - this service type is deprecated in favor of using PushKit for VoIP control

kCFStreamNetworkServiceTypeVoIP这个常量实际上早在iOS9就现已过期了。

甚至2016年,在CocoaAsyncSocket中Close的issue中就有反应这个问题:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

但是,在最新的2020年12月14日的CocoaAsyncSocket7.6.5版别中依旧仍是这么写的:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

既然kCFStreamNetworkServiceTypeVoIP现已过期了,那么我就用issuse 402里边提到的PKPushTypeVoIP替换一下试试。

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

编译,运转,App没有溃散!!!

将过期的kCFStreamNetworkServiceTypeVoIP改为运用PKPushTypeVoIP才是处理问题的关键!!!

复盘CocoaAsyncSocket的溃散过程(2022年9月16日更新)

更新完这篇文章后,我也收到了一些掘友的反应,说他们的CocoaAsyncSocket并没有呈现溃散状况,再加上我最近也一向到Github上看有关的问题,所以整理复盘一下。

首要,我要说的是,我呈现CocoaAsyncSocket的溃散,是由于我运用的CocoaMQTT导致的。

下面是截取的溃散定位的代码方位,详细状况能够看这里:Crash when build by Xcode 14.0 beta 5 (14A5294e) and run on iOS 16.0 (20A5339d)

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

而CocoaMQTTSocke的这个backgroundOnSocket默许属性上是true:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

由于我在自己项目里,并没有对backgroundOnSocket进行更改,所以就调用了CocoaAsyncSocket中的enableBackgroundingOnSocket()办法。

咱们接着持续搜索enableBackgroundingOnSocket()办法,所以能够看到它实质调用的是这个- (BOOL)enableBackgroundingOnSocketWithCaveat:(BOOL)caveat办法:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

最终咱们找到- (BOOL)enableBackgroundingOnSocketWithCaveat:(BOOL)caveat针对kCFStreamNetworkServiceTypeVoIP改为PKPushTypeVoIP的装备,真相也就大白了:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

最终也便是说自动调用CocoaAsyncSocket中的对外API- (BOOL)enableBackgroundingOnSocket;才会呈现溃散:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

这个bug现已埋藏久矣

这两天略微重视了一下CocoaAsyncSocket的PR与issues,真的是感觉有点哭笑不得,由于好久好久以前就有大佬提交了相关PR及其Bug的严重性,甚至苦口婆心的说要赶忙更新,否则死一大片,然而官方便是没有什么动态:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

感觉也是挺悲痛的,人家封闭这个issue的理由我也很震惊:

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

PushKit framework不支持全渠道,所以仍是用过期的API吧。而这一切的评论是在2015-2016年产生的。

一向过期一向爽,爽到溃散就好了。莫非就不能多些一点#if区别渠道来处理吗?

Version 7.6.5 will CRASH on iOS 16 due to removedkCFStreamNetworkServiceTypeVoIP#801

总结

在本篇,咱们处理了CocoaAsyncSocket在iOS16体系上的溃散问题,其实没有太多技巧而言。

咱们首要经过Xcode溃散的信息,根本定位到了CocoaAsyncSocket,然后在经过Github中的issuesPR,了解到了相关API的替换,最终发现kCFStreamNetworkServiceTypeVoIP现已过期了,运用之前现已有大佬提出的方案,就处理了这个问题。

还记得咱们之前简略计算吗?溃散只在iOS16的真机呈现,并且有开发者以为是iOS16 SDK的Bug导致

而我经过替换kCFStreamNetworkServiceTypeVoIP改为PKPushTypeVoIP处理这个问题后,我更倾向于这个观念:

在iOS16 SDK中,可能kCFStreamNetworkServiceTypeVoIP真的失效了,没有意义了,所以持续运用kCFStreamNetworkServiceTypeVoIP并不能完结装备,所以导致了溃散。

到这篇文章发布之前,我现已PR了代码到CocoaAsyncSocket,至于会不会被采纳,那就不知道了。

解决CocoaAsyncSocket在iOS16系统上的崩溃问题

考虑到触及运用CocoaAsyncSocket的App与第三库众多,也希望官方大佬早点处理这个问题吧。

参考文档

运用 CocoaAsyncSocket “kCFStreamNetworkServiceTypeVoIP is deprecated in iOS 9 ” warning 处理方案

kCFStreamNetworkServiceTypeVoIP is deprecated in iOS 9 warning

fix crash of backgrouding in iOS16

自己写的项目,欢迎大家star⭐️

RxStudy:RxSwift/RxCocoa结构,MVVM模式编写wanandroid客户端。

GetXStudy:运用GetX,重构了Flutter wanandroid客户端。