xcrun simctl bootxcrun simctl shutdownは、シミュレータデバイスを起動・終了するサブコマンドである。

参考: xcrun simctl createでiOSシミュレータデバイスを新規作成する

基本的な使い方

boot <device>で起動、shutdown <device>で終了する。

$ xcrun simctl boot "TIL Boot Test"
$ xcrun simctl list devices | grep "TIL Boot Test"
    TIL Boot Test (58E915DE-7D91-47A9-8DC4-25BDEB23E099) (Booted)

$ xcrun simctl shutdown "TIL Boot Test"
$ xcrun simctl list devices | grep "TIL Boot Test"
    TIL Boot Test (58E915DE-7D91-47A9-8DC4-25BDEB23E099) (Shutdown)

いずれもエラーがなければ何も出力されず、終了コードは0になる。

現在の状態と矛盾する操作はエラーになる

すでに起動中のデバイスにbootを実行したり、すでに終了しているデバイスにshutdownを実行したりすると、明確なエラーになる。

$ xcrun simctl boot "TIL Boot Test"
$ xcrun simctl boot "TIL Boot Test"
An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
Unable to boot device in current state: Booted

$ xcrun simctl shutdown "TIL Boot Test"
$ xcrun simctl shutdown "TIL Boot Test"
An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
Unable to shutdown device in current state: Shutdown

事前にsimctl list devices等で現在の状態を確認するか、エラーになる可能性を踏まえてスクリプトを組む必要がある。

参考: xcrun simctl cloneでiOSシミュレータデバイスを複製するxcrun simctl eraseでiOSシミュレータデバイスの内容を初期化する

cloneeraseも、起動中のデバイスに対して実行するとエラーになるサブコマンドである。

SIMCTL_CHILD_プレフィックスで環境変数を渡す

bootを実行するシェルの環境変数にSIMCTL_CHILD_プレフィックスを付けておくと、そのプレフィックスを除いた名前の環境変数として、デバイス内で起動されるプロセスに引き継がれる。

$ export SIMCTL_CHILD_TIL_TEST_VAR="hello-from-til"
$ xcrun simctl boot "TIL Boot Test"
$ xcrun simctl spawn "TIL Boot Test" /bin/sh -c 'echo $TIL_TEST_VAR'
hello-from-til

アプリの起動時に参照する環境変数をCIから注入したい場合などに使える。

--disabledJobでlaunchdジョブを無効化できるとされている

ヘルプには--disabledJob=<job>を指定すると、起動時に指定したlaunchdジョブを無効化できる(複数回指定して複数のジョブを無効化することも可能)と記載されている。

$ xcrun simctl boot "TIL Boot Test" --disabledJob=com.apple.SpringBoard

実際に試したところ、launchctl listでのPID有無やlaunchctl print-disabled system(無効化されたサービスの一覧表示)のいずれでも、効果を確認できなかった。 launchctl listのPID列は、ブート処理が完全に終わる前だとcom.apple.SpringBoardのPIDが一時的に付いていないことがあり、これを--disabledJobの効果と早合点しやすい(--disabledJobを指定しない場合でも同様にPIDなしの状態が観測できた)。 反対に、通常は無効化されているジョブを明示的に有効化する--enabledJob=<job>オプションもあるが、本記事ではこちらも動作確認していない。

--archはデバイスがサポートするアーキテクチャの範囲でのみ指定できる

--arch=<arch>で起動時のアーキテクチャを指定できるが、対象デバイスタイプがサポートしていないアーキテクチャを指定するとエラーになる。

$ xcrun simctl boot "TIL Boot Test" --arch=x86_64
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=22):
Requested architecture (x86_64) is not one of the devices supported architectures: (arm64)
Invalid argument

Apple SiliconのマシンでiPhone 16のような比較的新しいデバイスタイプを起動する場合、arm64以外のアーキテクチャは選択できない。

全デバイスを終了するshutdown all

shutdownallを指定すると、起動中の全デバイスを終了する。

$ xcrun simctl shutdown all

起動中の全デバイスに影響するため、実行には注意が必要である。