iOS 13 WKWebView上の動画をAVPlayerにすり替えてバックグラウンドで動画音声を再生するアプリを作って公開しているのですが、わかりにくいエラーに遭遇したのでシェアしておきます。同じエラーの検索で来た人の助けになればうれしいです。
現象
バックグラウンド状態になってからも動画の音声は再生され続けるのですが、約60秒でクラッシュし、Xcodeのログ上には次のように表示されます。実機でしか再現しません。
Message from debugger: Terminated due to signal 9
これだけじゃ何が原因かよくわからない。
以下のエラーはリリース済みアプリの同現象を Firebase Crashlytics が捉えたもの。
Fatal Exception: CALayerInvalidGeometry
CALayer position contains NaN: [nan nan]. Layer: <CALayer:0x282bad620; position = CGPoint (0 0); bounds = CGRect (0 0; 0 0); delegate = <UIView: 0x13de736c0; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; clipsToBounds = YES; animations = { opacity=<CABasicAnimation: 0x282b33f20>; }; layer = <CALayer: 0x282bad620>>; sublayers = (<CALayer: 0x282bae000>, <AVPlayerLayer: 0x282bad4c0>); mask = <CAShapeLayer: 0x282badf00>; masksToBounds = YES; allowsGroupOpacity = YES; opacity = 1; transform = CATransform3D (0 0 0 0; 0 0 0 0; 0 0 1 0; 0 0 0 1); backgroundColor = <CGColor 0x28091fe30> [<CGColorSpace 0x280e08a20> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 0 0.32 ); animations = [opacity=<CABasicAnimation: 0x282b33f20>]>
どちらのエラーからも明確な位置は特定できません。
Method SwizzlingでCALayer
のsetterプロパティを上書きして、すべての代入処理をログにはきだしてもNaNが入る余地はなかったので悩みました。
原因
細部に導入したアニメーションが実は高処理で、バックグラウンドでもCPUを消費していたことが原因でした。
Instruments の Time Profiler で異常値を発見してCPU消費を100%近くから一桁台へ抑えたところバックグラウンド再生が60秒を超えても動作するようになりました。
iOS 13でバックグラウンド処理が頻繁に落とされるとの情報も聞いていたのでビビりましたが、凡ミスだったようでよかったです。スッキリしたのでアプリを審査に出して寝ます。