【watchOS】拡張ランタイムセッションの強制終了【Extended Runtime Sessions】

拡張ランタイムセッションは、高いCPU使用率が続くとシステムによって強制終了されます。このあたりの内容はドキュメントの記載が薄く、ちょっと不親切です。私の方で動作確認などをして調べましたので、その内容をまとめて解説します。

拡張ランタイムセッションの強制終了とは

拡張ランタイムセッションは、通常、AppleWatchのスクリーンがオフされた後も、Frontmost(フォアグランド)のまま動作し続けることができる機能です。しかし、Frontmostのまま動作できるといっても、CPUを潤沢に使うことは許可されていません。一定時間、高いCPU使用率が続くと、システムによって強制的にセッションが終了させられます。

これが拡張ランタイムセッションの強制終了です。

強制終了の条件

強制終了の詳しい条件はドキュメントでは見つけることができません(2020年8月現在)。しかし、Xcodeの表示と、動作確認した結果から、おおよその条件はわかります。その条件は下記になります。

CPU使用率が15%を超えた状態が30秒〜50秒続く

15%という数値は、XcodeのデバッグセッションのCPU使用率のグラフ表示から推測しています。

拡張ランタイムセッション中のCPUモニタ

通常はCPU使用率だけが表示されますが、拡張ランタイムセッションが開始されると、グラフに「Average」と「Cap」が追加されます。

「Average」はその名前の通りCPU使用率の平均値だと思います。30秒以上の平均値をとっているようなので、値が落ち着くまで時間がかかります。

「Cap」は15%固定で、これが拡張ランタイムセッションの終了条件と思われます。

「Average」が「Cap」に近くと、強制終了が発生します。「Average」が落ち着くまで時間がかかるということもあり、「Average」の値が「Cap」に到達するより前に強制終了が発生します。

30秒〜50秒と言うのは、私の実験結果からです。何パターンか試してみて、この数値になりました。詳しい条件はわかりませんが、ご参考までに。

強制終了の検出

拡張ランタイムセッションの強制終了が発生したら、何かしらの処理を行いたいと思うことでしょう。その場合は、WKExtendedRuntimeSessionDelegateのメソッドを使います。

func extendedRuntimeSession(_ extendedRuntimeSession: WKExtendedRuntimeSession, didInvalidateWith reason: WKExtendedRuntimeSessionInvalidationReason, error: Error?) {
    print("[Extended Runtime Sessions] invalidated")
    if error != nil {
        // エラー処理
    }
}

これはセッションが終了した時に呼び出されるメソッドです。強制終了させられた時は引数にエラーが入っているので、それを見て判断します。