【watchOS】拡張ランタイムセッションを解説【Extended Runtime Sessions】

拡張ランタイムセッションとは、腕を下げたあとなど、通常はアプリが停止する場合でも、アプリを動かし続けることができる機能のことです。本記事では、この拡張ランタイムセッションについて詳しく解説します。

拡張ランタイムセッションの概要

通常、Apple Watchアプリは、ユーザーが腕を下げた時、Background状態の後にSuspended状態になります。そうするとアプリは動作しなくなってしまいますが、その対処法として次の2つの方法があります。

  • バックグラウンドセッション
  • 拡張ランタイムセッション

バックグラウンドセッション

バックグラウンドセッションを使うと、アプリはBackgroundで動作をし続けます。しかし、このセッションは以下のモニタリングでしか利用できません。

  • ワークアウト
  • ユーザのロケーションの追跡
  • 音声ファイルの再生

拡張ランタイムセッション

拡張ランタイムセッションは、Watchのスクリーンがオフされた後も、Bluetooth通信、データ処理、音声や触覚フィードバックを再生することができます。これはWatchOS6からの新機能です。

セッションには種類があり、Backgroundで動作するものや、Active(Frontmost)で動作するものがあります。

  • Self care
    • ユーザの比較的短い時間のアクティビティのために使用します。
    • アクティビティは、歯磨きなどの、ユーザの幸福や健康にフォーカスしたものです。
  • Mindfulness
    • 静かな瞑想の開始と終了を手助けします。
    • 歩きながらの瞑想であれば、バックグラウンドセッションのWorkout processingを考慮してください。
    • 瞑想している間、音楽を聞いているのであれば、バックグラウンドセッションのAudioを使います。
  • Physical therapy
    • ストレッチ、筋トレ、柔軟体操などで使用します。
    • 激しい動き(例えば、エクササイズバイクに乗る場合)であれば、バックグラウンドセッションのWorkout processingを考慮してください。
  • Smart alarm
    • ユーザの心拍数と動きをモニターするための時間間隔をスケジュールします。
    • アラームを再生する適切な時間を決めるために使用します。通常は眠りから覚める時に使うでしょう。

複数のセッションがあり機能的に特徴が違いますが、その特徴でセッションを選ぶのではなく、使用意図にあったセッションを選ぶように、と公式ドキュメントにあります。

重要!
Apple Watchの高いパフォーマンスを維持するために、拡張ランタイムセッションの間はワークの数を制限してください。もし、高いCPU使用率が続くようであれば、そのセッションはキャンセルされます(WKExtendeRuntimeSessionErrorCode.exceededResourceLimits)。XcodeのCPU report tool、もしくはInstrumentsにあるtime profilerを使って、CPU使用率の確認と最小化をしてください。

拡張ランタイムセッションの各セッションの挙動

セッションの種類によって挙動が変わります。

種類ランタイムスケジュール時間制限
Self careFrontmostNo10分
MindfulnessFrontmostNo1時間
Physical therapyBackgroundNo1時間
Smart alarmBackgroundYes30分

ランタイムのFrontmostとBackground

Frontmostでは、アプリはフォアグラウンドで動作を続けます。スクリーンはオフになっているかもしれません。このセッションが終了するのは下記の3パターンがあります。

  • 制限時間を過ぎる
  • アプリが自分でInvalidateする
  • ユーザの操作(デジタルクラウンを押す、別のアプリに切り替える)

Backgroundでは、アプリはバックグラウンドで動作を続けます。Frontmostの場合と違い、ユーザがデジタルクラウンを押したり、別のアプリに切り替えてもセッションを継続します。

スケジュール

Smart alarmでのみセッションの開始をスケジュールできます。スケジュールすると、システムはアプリを終了することができ、スケジュールされた時刻になるとアプリを再起動します。

36時間以内であればどの時間でもスケジューリングが可能です。

再起動したあと、30分間はセッションを維持します。

拡張ランタイムセッションの使い方

使用するセッションの選択

まずはアプリで使用するセッションを選択します。次の手順で選択できます。

  • XcodeのTARGETS -> アプリ(Watch Extension) -> Signing & Capabilitiesを開く
  • 「+Capability」をクリックして「Background Modes」を追加
  • Session Typeでセッションを選択

拡張ランタイムセッションは1つのアプリにつき1つしか選択できません。バックグラウンドセッションとは、組み合わせて使用できます。

セッションを開始する準備

実際にコード上でセッションを使ってみましょう。セッションを使うには、下記の2つを利用します。

  • WKExtendedRuntimeSession
  • WKExtendedRuntimeSessionDelegate

名前からしてなんとなくイメージは湧くと思います。WKExtendedRuntimeSessionを使って、セッションの開始と終了を行います。WKExtendedRuntimeSessionDelegateはセッションに関連するイベントを受け取るためのプロトコルです。

これらを使う準備をしましょう。

session = WKExtendedRuntimeSession()
session.delegate = self

このコードはセッションの生成とデリゲートを指定しています。

次にデリゲートメソッドを用意します。

func extendedRuntimeSessionDidStart(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
    print("didInvalidateWith reason=\(reason)")
}

func extendedRuntimeSessionWillExpire(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
    print("extendedRuntimeSessionWillExpire")
}
    
func extendedRuntimeSession(_ extendedRuntimeSession: WKExtendedRuntimeSession, didInvalidateWith reason: WKExtendedRuntimeSessionInvalidationReason, error: Error?) {
    print("didInvalidateWith reason=\(reason)")
}

extendedRuntimeSessionDidStart()は、セッションが開始されると呼び出されます。

extendedRuntimeSessionWillExpire()は、セッションには制限時間があり、その制限時間を過ぎるとこのメソッドが呼び出されます。

extendedRuntimeSession()は、セッションが上記の制限時間以外の理由で終了すると呼び出されます。

セッションの開始と終了(Smart alarm以外の場合)

それではセッションの開始の仕方をみてみましょう。セッションを開始するにはstart()メソッドを使います。

session = WKExtendedRuntimeSession()
session.delegate = self

session.start()

1つ注意しなければならないのは、セッションの開始はアプリがWKApplicationState.activeである時に行わなければならないことです。

セッションの終了ですが、これは制限時間を待つか、コードから終了させることができます。制限時間がたった時は先ほどのデリゲートメソッドが呼び出されます。コードから終了させるにはinvalidate()メソッドを使います。

session.invalidate()

これも非常に簡単ですね。なお、アプリがアクティブな時はこのinvalidate()でのみセッションを終了させることができます。

セッションの開始と終了(Smart alertの場合)

Smart alarmタイプのセッションの場合は、セッションの開始をスケジュールします。その時は、引数で開始時刻をDateで指定します。

session.start(at: date)

スケジュールは1セッションにつき1度しか行えません。もし、再スケジュールが必要であれば、セッションをinvalidate()して作り直してください。

次にスケジュールされた時刻になった時の処理を書きます。

func handle(_ extendedRuntimeSession: WKExtendedRuntimeSession) {
    print("handle")
}

スケジュールされた時刻になると、アプリが再起動されてhandle(_:)メソッドが呼び出されます。handle(_:)メソッドが実装されていなければ、そのセッションはそのまま終了してしまいます。

セッションが開始されると、アプリはバックグラウンドのまま動作を続けます。これは制限時間になるか、あるいはアプリがinvalidate()するまで続きます。

このセッションの間にnotifyUser(hapiticType:repeathandler:)メソッドでアラームを出すことができます。詳しくは、notifyUser(hapiticType:repeathandler:)を確認してください。

もし、セッションの制限時間の間にアラームを出せなかったら、システムはワーニングを表示し、将来のセッションを無効化することを提案してきます。

参考URL

Using Extended Runtime Sessions