こんにちは!エンジニアの柳村です。
9月末頃からママリのiOSアプリでWebThread関連のクラッシュが増加し、ときどき爆増するといった事が起こりました。
クラッシュレポートを調べてみると以下の3つクラッシュが多数発生していました。
Crashed: WebThread 0 JavaScriptCore 0x1a583e14c WTFCrashWithInfo(int, char const*, char const*, int) + 20 1 JavaScriptCore 0x1a5d21b3c JSC::Interpreter::prepareForRepeatCall(JSC::FunctionExecutable*, JSC::ExecState*, JSC::ProtoCallFrame*, JSC::JSFunction*, int, JSC::JSScope*, JSC::ArgList const&) + 742 2 JavaScriptCore 0x1a5f808c0 JSC::boundFunctionConstruct(JSC::ExecState*) + 588
Crashed: WebThread 0 JavaScriptCore 0x19407aad4 <redacted> + 20 1 JavaScriptCore 0x1948013dc <redacted> + 746 2 JavaScriptCore 0x194a80b50 <redacted> + 608
Crashed: WebThread 0 libGPUSupportMercury.dylib 0x1d8145fe4 gpus_ReturnNotPermittedKillClient 1 AGXGLDriver 0x1dc7f2ed8 (シンボルが不足しています) 2 libGPUSupportMercury.dylib 0x1d8146fac gpusSubmitDataBuffers 3 AGXGLDriver 0x1dc7f4404 (シンボルが不足しています) 4 IOAccelerator 0x1be209884 IOAccelContextFinishResourceSysMem + 64
見ての通り、どれもなるほどわからんというエラーですね・・・
しかも、アプリやiOSのアップデートとは関係なく急増するという不思議な状況でした。
原因の分析
ママリのiOSアプリではいくつかWebViewを使っている箇所があり、どこのWebViewが原因かをまず洗い出す必要がありました。
ママリのiOSアプリではFirebase Crashlyticsを利用しており、Firebase Crashlyticsだとクラッシュレポートとログが一緒に見れるのでどの画面でクラッシュしたか判断するのに役に立ちました。
調べた結果は起動直後にクラッシュしているユーザーがいたのでトップページのどこかであるということに絞れました。
しかし、トップページにWebViewは使った心当たりはなかったので、XcodeのDebug View Hierarchy
を使ってどこでWebViewが使われているか調査しました。
その結果Google Mobile AdsのDFPBannerView内でUIWebViewが使われていることがわかりました。
対策
まずはSDKが古かったので最新(7.50.0)にしてみましたが効果はありませんでした。。
そこでGoogle Mobile Adsのフォーラムを見たところUIWebViewをWKWebViewに変えることができるとの情報が得られたのでやってみました。
以下のようにinfo.plistにgad_preferred_webview
というKeyとwkwebview
というValueを設定するとWKWebViewに変えることができました。
<key>gad_preferred_webview</key> <string>wkwebview</string>
これをリリースしたところ、多数発生していたクラッシュがWKWebViewにしたバージョンでは発生しなくなりました!
まとめ
急にWebThread関連のエラーが増えて、Google Mobile Adsを使っている場合はinfo.plistを変更してWKWebViewに変えるとよいです。
UIWebViewはiOS13ではdeprecatedになっていますし、iOS13でUIWebViewでwindow.confirm
を使うと挙動がおかしかったりするということも弊社で確認しているので、UIWebViewは捨て去ったほうがよいかと思います。