ゴールデン ストーン プロジェクトの最初のチャレンジにサインアップしました - 賞金プール 100,000 を共有します。これは私の 2 回目の記事です。クリックしてイベントの詳細を表示します
この記事では、昨日の iOS16 アップデートで発見されたクラッシュから解決までのプロセスについて説明します。
序文
昨日、中秋節の翌日、アップルの父親がiOS16システムをプッシュしました。
そこで、iOS 開発者の通常の作業として、長いアップグレード ロードを開始しました。
- macOS を 12.6 にアップグレードする
- iOS16にアップグレード
- Xcode14 をアップグレードする
アプリを実行してからクラッシュします。クラッシュのスクリーンショット情報は次のとおりです。
クラッシュの再現が簡単
Xcode14 は、その後の継続的な開発に必要な IDE バージョンであるため (理論的には、Xcode13 を引き続き開発に使用できますが、iOS16 では Xcode14 を使用することをお勧めします)、クラッシュの問題の簡単な再現統計を作成しました。
IDE バージョン | iOS版 | 装置 | クラッシュしますか |
---|---|---|---|
Xcode14 | iOS15 | 実機 | 番号 |
Xcode14 | iOS15 | エミュレータ | 番号 |
Xcode14 | iOS16 | 実機 | はい |
Xcode14 | iOS16 | エミュレータ | 番号 |
クラッシュは iOS16 の実機でのみ発生していることがわかります。
配置に関する問題のトラブルシューティング
CocoaMQTT
情報によると、関連する依存ライブラリでクラッシュの問題が発生していることがわかります-- CocoaAsyncSocket
。
CocoaMQTT
そこで、いくつかの未解決の問題を確認するためにトップに行きました。
8 月 15 日に提出されたフィードバックの問題がありますが、おそらく Xcode14 の beta5 でクラッシュが発生しているというもので、それも関係していCocoaAsyncSocket
ます。
そのため、つるをたどり、依存ライブラリを探し続けましたCocoaAsyncSocket
。
案の定、問題は非常に目を引くものです:
これは iOS 16 Core Foundation フレームワーク内の問題だと思います。新しい Core Foundation のソース コードは公開されていないため、Apple にバグを報告するだけです (FB11489606)。
根据反馈者的意见:认为这个bug可能是由于iOS16架包中的Core Foundation framework导致。
于是我们又顺带看了看CocoaAsyncSocket
的PR:
第一个PR就格外醒目!解决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中就有反馈这个问题:
但是,在最新的2020年12月14日的CocoaAsyncSocket
的7.6.5
版本中依旧还是这么写的:
既然kCFStreamNetworkServiceTypeVoIP
已经过期了,那么我就用issuse 402
里面提到的PKPushTypeVoIP
替换一下试试。
编译,运行,App没有崩溃!!!
将过期的kCFStreamNetworkServiceTypeVoIP改为使用PKPushTypeVoIP才是解决问题的关键!!!
总结
在本篇,我们解决了CocoaAsyncSocket
在iOS16系统上的崩溃问题,其实没有太多技巧而言。
我们首先通过Xcode崩溃的信息,基本定位到了CocoaAsyncSocket
,然后在通过Github中的issues
和PR
,了解到了相关API的替换,最后发现kCFStreamNetworkServiceTypeVoIP
已经过期了,使用之前已经有大佬提出的方案,就解决了这个问题。
还记得我们之前简单统计吗?崩溃只在iOS16的真机出现,而且有开发者认为是iOS16 SDK的Bug导致。
而我通过替换kCFStreamNetworkServiceTypeVoIP改为PKPushTypeVoIP解决这个问题后,我更倾向于这个观点:
在iOS16 SDK中,可能kCFStreamNetworkServiceTypeVoIP
真的失效了,没有意义了,所以继续使用kCFStreamNetworkServiceTypeVoIP并不能完成配置,所以导致了崩溃。
到这篇文章发布之前,我已经PR了代码到CocoaAsyncSocket
,至于会不会被采纳,那就不知道了。
考虑到涉及使用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 クライアントがリファクタリングされました。