ios-simulator について
Simulator と `xcrun simctl` を使う iOS 開発者向けのリファレンススキルです。デバイス管理、アプリのインストールとテストに加え、ログ、画面収録、シミュレーターの制限を扱い、デバッグや CI に役立ちます。
主な機能
- 01シミュレーターデバイスのライフサイクル管理
- 02アプリのインストール、起動、終了
- 03プッシュ、位置情報、権限のシミュレーション
- 04スクリーンショットと動画の撮影
- 05ログのストリーミングとフィルタリング
- 06シミュレーターの機能制限の説明
活用シーン
- 01CI でのシミュレーター起動と後処理
- 02プッシュペイロードとディープリンクのテスト
- 03位置情報とプライバシー権限のシミュレーション
- 04アプリのログとスクリーンショットの取得
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dpearson2699/ swift-ios-skills --skill ios-simulatorインストール後、Claude Code で/ios-simulatorを入力して読み込まれたか確認します。
同梱ファイルevals/evals.jsonreferences/simctl-commands.md
詳細
iOS Simulator
コマンド一覧、JSON の解析、プライバシー/ステータスバーの値、Logger のフィルター設定、または起動復旧コマンドが必要な場合は、simctl コマンドリファレンスを読み込んでください。
目次
- デバイスのライフサイクル
- アプリのインストールと起動
- テストのワークフロー
- スクリーンショットとビデオの録画
- ログのストリーミング
- コンパイル時の Simulator 検出
- Simulator の制限事項
- よくある間違い
- 確認チェックリスト
- 参考資料
デバイスのライフサイクル
デバイスとランタイムの一覧表示
# List all available simulators grouped by runtime
xcrun simctl list devices available
# List installed runtimes
xcrun simctl list runtimes
# List only booted devices
xcrun simctl list devices booted
# JSON output for scripting
xcrun simctl list -j devices available
JSON 出力を解析すると、特定のデバイスをプログラムで見つけられます。jq による解析例については、references/simctl-commands.mdを参照してください。
デバイスの作成
# Find available device types and runtimes
xcrun simctl list devicetypes
xcrun simctl list runtimes
# Create a device — returns the new UDID
xcrun simctl create "My Test Phone" "iPhone 16 Pro" "com.apple.CoreSimulator.SimRuntime.iOS-18-4"
このスキル全体の例にあるデバイスタイプとランタイム識別子は、説明用です。simctl list devicetypes と simctl list runtimes を実行して、システムで利用可能な識別子を確認してください。
以降のコマンドでは、返された UDID を使用してください。
起動、シャットダウン、消去、削除
# Boot a specific device
xcrun simctl boot <UDID>
# Boot if needed and wait until the device is ready
xcrun simctl bootstatus <UDID> -b
# Shutdown a running device
xcrun simctl shutdown <UDID>
# Factory reset — wipes all data, keeps the device
xcrun simctl erase <UDID>
# Delete a specific device
xcrun simctl delete <UDID>
# Delete all devices not available in the current Xcode
xcrun simctl delete unavailable
# Shutdown everything
xcrun simctl shutdown all
実行中の Simulator が 1 台だけの場合は、UDID の省略形として booted を使用できます。
xcrun simctl shutdown booted
複数の Simulator が起動している場合、booted はそのうちの 1 台を非決定的に選びます。Simulator を並行して実行する場合は、明示的な UDID を使用してください。
スクリプトや CI では、インストール、起動、プッシュ、または位置情報コマンドを実行する前の、起動と準備完了の確認手段として xcrun simctl bootstatus <UDID> -b が正式な方法です。
アプリのインストールと起動
アプリのインストール
# Build for simulator first
xcodebuild build \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro' \
-derivedDataPath build/
# Boot and wait for SpringBoard/services before install
xcrun simctl bootstatus <UDID> -b
# Install the .app bundle
xcrun simctl install <UDID> build/Build/Products/Debug-iphonesimulator/MyApp.app
指定するパスは、Simulator のアーキテクチャ向けにビルドされた .app ディレクトリを指す必要があります。.ipa ファイルは指定できません。
起動と終了
# Launch by bundle ID
xcrun simctl launch booted com.example.MyApp
# Launch and stream stdout/stderr to the terminal
xcrun simctl launch --console booted com.example.MyApp
# Pass launch arguments
xcrun simctl launch booted com.example.MyApp --reset-onboarding -AppleLanguages "(fr)"
# Terminate a running app
xcrun simctl terminate booted com.example.MyApp
--console はデバッグに便利です。print() と os_log の出力をターミナルに直接表示します。
アプリのコンテナパス
# App bundle location
xcrun simctl get_app_container booted com.example.MyApp app
# Data container (Documents, Library, tmp)
xcrun simctl get_app_container booted com.example.MyApp data
# Shared app group container
xcrun simctl get_app_container booted com.example.MyApp group.com.example.shared
テストのワークフロー
プッシュ通知のシミュレーション
JSON ペイロードファイルを作成します。
{
"aps": {
"alert": {
"title": "New Message",
"body": "You have a new message from Alice"
},
"badge": 3,
"sound": "default"
},
"customKey": "customValue"
}
Simulator に送信します。
# Send push payload from file
xcrun simctl push booted com.example.MyApp payload.json
# Pipe payload from stdin
echo '{"aps":{"alert":"Quick test"}}' | xcrun simctl push booted com.example.MyApp -
これはローカルでのペイロード処理と通知 UI をテストするものであり、APNs による配信はテストしません。
位置情報のシミュレーション
# Set a fixed coordinate (latitude, longitude)
xcrun simctl location booted set 37.3349,-122.0090
# List available predefined scenarios
xcrun simctl location booted list
# Run a predefined scenario
xcrun simctl location booted run "City Run"
# Follow custom command-line waypoints
xcrun simctl location booted start --speed=15 --interval=1 \
37.3349,-122.0090 37.3317,-122.0307
# Read waypoints from stdin, one "lat,lon" pair per line
printf "37.3349,-122.0090\n37.3317,-122.0307\n" | \
xcrun simctl location booted start --distance=100 -
# Clear the simulated location
xcrun simctl location booted clear
1 つの座標には set、定義済みのシナリオ名には run、カスタムのウェイポイントルートには start を使用します。コマンドの使い分けが重要です。simctl location run が受け付けるのは、組み込みのシナリオ名(例:「City Run」、「Freeway Drive」)であり、GPX ファイルのパスではありません。カスタム座標のウェイポイントには、コマンドラインから simctl location start を使用します。GPX に基づくルートには、Xcode の「Debug」>「Simulate Location」メニューを使用してください。
位置情報のシミュレーションは、起動中のデバイスで Core Location を使用するすべてのアプリに影響します。予期しないテスト結果を避けるため、完了したら位置情報をクリアしてください。
プライバシー権限
# Grant a permission
xcrun simctl privacy booted grant photos com.example.MyApp
# Revoke a permission
xcrun simctl privacy booted revoke microphone com.example.MyApp
# Reset all permissions for the app
xcrun simctl privacy booted reset all com.example.MyApp
一般的なサービス名:photos、microphone、contacts、calendar、reminders、location、location-always、motion、siri。すべての一覧については、references/simctl-commands.mdを参照してください。
CI で権限を事前に許可すると、自動テストの実行を妨げるシステム権限ダイアログを回避できます。ただし、必要な使用目的の説明キーが欠けていても気づけない場合があります。Info.plist に必要なプライバシー文字列を残し、通常のプロンプトフローもテストしてください。
ディープリンクと URL
# Open a URL (triggers universal links or custom URL schemes)
xcrun simctl openurl booted "https://example.com/product/123"
# Custom URL scheme
xcrun simctl openurl booted "myapp://settings/notifications"
ユニバーサルリンクを使用するには、アプリの Associated Domains エンタイトルメントを設定する必要があります。Simulator は、そのドメインの apple-app-site-association ファイルを使用します。
ステータスバーのオーバーライド
# Set a clean status bar for screenshots
xcrun simctl status_bar booted override \
--time "9:41" \
--batteryState charged \
--batteryLevel 100 \
--cellularMode active \
--cellularBars 4 \
--wifiBars 3 \
--operatorName ""
# Clear all overrides
xcrun simctl status_bar booted clear
App Store のスクリーンショットを統一するには、ステータスバーのオーバーライドを使用してください。ほかのテストに混乱を招かないよう、撮影後は必ずオーバーライドをクリアしてください。
スクリーンショットとビデオの録画
# Capture a screenshot
xcrun simctl io booted screenshot screenshot.png
# Record video (press Ctrl+C to stop)
xcrun simctl io booted recordVideo recording.mov
# Screenshot with specific display mask
xcrun simctl io booted screenshot --mask black screenshot.png
--mask オプション:ignored(デフォルト、マスクなし)、alpha(角を透明にする)、black(角を黒くする)。デバイスの形状がわかるスクリーンショットを撮る場合は、alpha または black を使用してください。alpha マスクはスクリーンショットのみ対応しています。ビデオ録画では black にフォールバックします。
ビデオ録画は、プロセスが SIGINT(Ctrl+C)を受信するまで続きます。録画は停止後にのみ保存されます。プロセスを SIGKILL で強制終了すると、ファイルは失われます。
ログストリーミング
基本的なログストリーム
# Stream all logs at debug level and above
xcrun simctl spawn booted log stream --level debug
# Filter by subsystem
xcrun simctl spawn booted log stream --level debug \
--predicate 'subsystem == "com.example.app"'
# Filter by subsystem and category
xcrun simctl spawn booted log stream --level debug \
--predicate 'subsystem == "com.example.app" AND category == "networking"'
# Filter by process name
xcrun simctl spawn booted log stream \
--predicate 'process == "MyApp"'
Logger のサブシステム/カテゴリと、一致する log stream
述語の定義については、Logger and Filtered Streaming
を参照してください。
コンパイル時のシミュレーター判定
シミュレーターで実行できないコードを除外するには、#if targetEnvironment(simulator) を使用してください。
func registerForPush() {
#if targetEnvironment(simulator)
logger.info("Skipping APNs registration — running in Simulator")
#else
UIApplication.shared.registerForRemoteNotifications()
#endif
}
環境変数を使った実行時の判定:
var isSimulator: Bool {
ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
}
実行時のチェックより、コンパイル時のチェック(#if targetEnvironment(simulator))を優先してください。コンパイラーが除外対象のコードを完全に取り除くため、使用できないシンボルによるリンカーエラーを防げます。
シミュレーターの制限事項
以下の表を正式な分類として使用してください。トリガーやプロキシがサポートされていても、実機と同等の動作が保証されるわけではありません。
| 機能 | シミュレーターのサポート状況 |
|---|---|
| APNs プッシュ配信 | 非対応 — ローカルでのシミュレーションには simctl push を使用してください |
| パフォーマンスの再現性 | 相対的な比較のみ — シミュレーターは CPU/処理性能、ネットワーク速度、グラフィックス/Metal、メモリ帯域幅、フレームタイミング、メモリプレッシャー、Jetsam、シェーダーの正確性、熱挙動を正確に再現しません。パフォーマンスが重要な処理はハードウェア上で検証してください |
| Metal GPU ファミリーの同等性 | 部分的 — シミュレーターはデバイスの GPU ではなくホスト Mac の GPU を使用するため、一部のシェーダーや制限が異なります |
| カメラハードウェア | 非対応 — 写真ライブラリへのデータ投入、または AVCaptureSession のモックを使用してください |
| 音声入力/マイク | アプリの一般的な音声入力には非対応です。Siri はシミュレーターのメニューから起動できます |
| Secure Enclave | 非対応 — kSecAttrTokenIDSecureEnclave の操作は失敗します |
| App Attest(DCAppAttestService) | 非対応 — isSupported は false を返します |
| DockKit のモーター制御 | 非対応 — 物理アクセサリを接続できません |
| 加速度計/ジャイロスコープ | モーションセンサーには非対応です。モーションに依存する動作には実機を使用してください |
| 気圧計 | 非対応 |
| NFC(Core NFC) | 非対応 |
| Bluetooth(Core Bluetooth) | 非対応 — BLE のテストには実機を使用してください |
| CarPlay ディスプレイのシミュレーション | シミュレーターの外部ディスプレイ/CarPlay オプションでサポートされています。ただし、車載環境またはデバイスの構成でも検証してください |
| Face ID/Touch ID ハードウェア | ハードウェアには非対応 — シミュレーターの「Features > Face ID / Touch ID」メニューを使用してください |
| メモリ警告、位置情報の変更、iCloud 同期の手動トリガー | シミュレーターのメニューまたは simctl でサポートされています。手動同期ではアプリのコールバック処理をテストできます |
| iCloud の自動反映と競合 | 実際のアカウント/デバイスでの検証が必要です。通知をトリガーとする同期、バックグラウンド配信、競合、アカウント/デバイス状態の違いが対象です |
| 携帯電話ネットワークの状態 | 非対応 — Mac の Network Link Conditioner を使用してください |
よくある間違い
しないでください:スクリプト内にシミュレーターの UDID をハードコードする
シミュレーターを削除して再作成すると UDID が変わります。値をハードコードすると、他のマシンや CI で動作しなくなります。
# WRONG — hardcoded UDID
xcrun simctl boot "A1B2C3D4-E5F6-7890-ABCD-EF1234567890"
# CORRECT — look up by name and runtime
UDID=$(xcrun simctl list -j devices available | \
jq -r '.devices["com.apple.CoreSimulator.SimRuntime.iOS-18-4"][] | select(.name == "iPhone 16 Pro") | .udid')
xcrun simctl boot "$UDID"
# CORRECT — use "booted" when one simulator is running
xcrun simctl install booted MyApp.app
しないでください:シャットダウン中のシミュレーターにインストールまたは起動する
simctl install と simctl launch には、起動済みのデバイスが必要です。シャットダウン中のデバイスでは、エラーが表示されないか、わかりにくいエラーが発生します。
# WRONG — device is not booted
xcrun simctl install <UDID> MyApp.app # fails
# CORRECT — boot if needed and wait for readiness, then install
xcrun simctl bootstatus <UDID> -b
xcrun simctl install <UDID> MyApp.app
xcrun simctl launch <UDID> com.example.MyApp
しないでください:ゾンビシミュレーターを CI で実行したままにする
起動中のシミュレーターはそれぞれメモリと CPU を消費します。後処理をせずにシミュレーターを作成する CI パイプラインでは、ゾンビデバイスが蓄積します。
# WRONG — CI script creates and boots but never cleans up
xcrun simctl create "CI Phone" "iPhone 16 Pro" "com.apple.CoreSimulator.SimRuntime.iOS-18-4"
xcrun simctl boot "$UDID"
# ... tests run, pipeline exits ...
# CORRECT — always clean up in CI teardown
cleanup() {
xcrun simctl shutdown all
xcrun simctl delete "$UDID"
}
trap cleanup EXIT
しないでください:応答しなくなったシミュレーターの起動を何度も試す
「Booting」状態で停止したシミュレーターは、boot を再試行しても復旧しません。基盤となる CoreSimulator の状態が破損しています。
# WRONG — retry loop on a stuck device
xcrun simctl boot "$UDID" # "Unable to boot device in current state: Booting"
xcrun simctl boot "$UDID" # same error, forever
# CORRECT — shut down, erase, and retry
xcrun simctl shutdown "$UDID"
xcrun simctl erase "$UDID"
xcrun simctl boot "$UDID"
# If that fails, reset CoreSimulator entirely
xcrun simctl shutdown all
xcrun simctl erase all
# Last resort: rm -rf ~/Library/Developer/CoreSimulator/Caches
レビューチェックリスト
- シミュレータデバイスの作成時に、デバイスタイプとランタイム識別子を明示する
- スクリプトでは、ハードコードされた値ではなく、JSON 出力から
bootedまたは解析した UDID を使用する - 開発中に
simctl pushを使用してプッシュ通知のペイロードをテストする - リリース前に実機でプッシュ通知の配信を確認する
- 必要に応じて、固定座標、定義済みのシナリオ、カスタムウェイポイントを使用して位置情報のシミュレーションをテストする
- ダイアログによる処理の中断を避けるため、CI でプライバシー権限を事前に許可する
- Simulator で利用できない API の周囲に
#if targetEnvironment(simulator)ガードを設ける - スクリーンショットの撮影後に、ステータスバーのオーバーライドを解除する
- CI パイプラインのティアダウン時に、シミュレータをシャットダウンして削除する
- 集中的なデバッグのために、サブシステム/カテゴリの述語を使ってログストリーミングを設定する
- デバッグ中にサンドボックス化されたデータを調べる際は、アプリコンテナのパスを使用する