ios-simulator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseiOS Simulator
iOS Simulator
Manage iOS Simulator devices and test app behavior from the command line using . Covers the full device lifecycle, app deployment, push and location simulation, permission control, screenshot and video recording, log streaming, and compile-time simulator detection.
xcrun simctlFor the complete subcommand reference with all flags and options, see references/simctl-commands.md.
使用从命令行管理iOS Simulator设备并测试应用行为。涵盖完整的设备生命周期、应用部署、推送与位置模拟、权限控制、截图与录屏、日志流以及编译时模拟器检测。
xcrun simctl如需包含所有标志和选项的完整子命令参考,请查看references/simctl-commands.md。
Contents
目录
Device Lifecycle
设备生命周期
Listing Devices and Runtimes
列出设备与运行时
bash
undefinedbash
undefinedList all available simulators grouped by runtime
按运行时分组列出所有可用模拟器
xcrun simctl list devices available
xcrun simctl list devices available
List installed runtimes
列出已安装的运行时
xcrun simctl list runtimes
xcrun simctl list runtimes
List only booted devices
仅列出已启动的设备
xcrun simctl list devices booted
xcrun simctl list devices booted
JSON output for scripting
输出JSON格式用于脚本编写
xcrun simctl list -j devices available
Parse JSON output to find a specific device programmatically. See [references/simctl-commands.md](references/simctl-commands.md) for `jq` parsing examples.xcrun simctl list -j devices available
通过解析JSON输出以编程方式查找特定设备。有关`jq`解析示例,请查看[references/simctl-commands.md](references/simctl-commands.md)。Creating a Device
创建设备
bash
undefinedbash
undefinedFind available device types and runtimes
查找可用的设备类型和运行时
xcrun simctl list devicetypes
xcrun simctl list runtimes
xcrun simctl list devicetypes
xcrun simctl list runtimes
Create a device — returns the new UDID
创建设备 — 返回新的UDID
xcrun simctl create "My Test Phone" "iPhone 16 Pro" "com.apple.CoreSimulator.SimRuntime.iOS-18-4"
Device types and runtime identifiers in examples throughout this skill are illustrative. Run `simctl list devicetypes` and `simctl list runtimes` to find the identifiers available on your system.
The returned UDID identifies the device for all subsequent commands. Use descriptive names to distinguish devices in `simctl list` output.xcrun simctl create "My Test Phone" "iPhone 16 Pro" "com.apple.CoreSimulator.SimRuntime.iOS-18-4"
本文示例中的设备类型和运行时标识符仅作说明。请运行`simctl list devicetypes`和`simctl list runtimes`查找系统上可用的标识符。
返回的UDID用于后续所有命令标识该设备。请使用描述性名称以便在`simctl list`输出中区分不同设备。Boot, Shutdown, Erase, Delete
启动、关闭、擦除、删除
bash
undefinedbash
undefinedBoot a specific device
启动特定设备
xcrun simctl boot <UDID>
xcrun simctl boot <UDID>
Shutdown a running device
关闭运行中的设备
xcrun simctl shutdown <UDID>
xcrun simctl shutdown <UDID>
Factory reset — wipes all data, keeps the device
恢复出厂设置 — 清除所有数据,保留设备
xcrun simctl erase <UDID>
xcrun simctl erase <UDID>
Delete a specific device
删除特定设备
xcrun simctl delete <UDID>
xcrun simctl delete <UDID>
Delete all devices not available in the current Xcode
删除当前Xcode中不可用的所有设备
xcrun simctl delete unavailable
xcrun simctl delete unavailable
Shutdown everything
关闭所有设备
xcrun simctl shutdown all
Use `booted` as a UDID shorthand when exactly one simulator is running:
```bash
xcrun simctl shutdown bootedIf multiple simulators are booted, picks one of them non-deterministically. Prefer explicit UDIDs when running parallel simulators.
bootedxcrun simctl shutdown all
当仅有一个模拟器运行时,可使用`booted`作为UDID的简写:
```bash
xcrun simctl shutdown booted如果多个模拟器已启动,会非确定性地选择其中一个。运行并行模拟器时,建议使用明确的UDID。
bootedApp Install and Launch
应用安装与启动
Installing an App
安装应用
bash
undefinedbash
undefinedBuild for simulator first
先为模拟器构建应用
xcodebuild build
-scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
-derivedDataPath build/
-scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
-derivedDataPath build/
xcodebuild build
-scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
-derivedDataPath build/
-scheme MyApp
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
-derivedDataPath build/
Install the .app bundle
安装.app包
xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/MyApp.app
The path must point to a `.app` directory built for the simulator architecture, not a `.ipa` file.xcrun simctl install booted build/Build/Products/Debug-iphonesimulator/MyApp.app
路径必须指向为模拟器架构构建的`.app`目录,而非`.ipa`文件。Launching and Terminating
启动与终止
bash
undefinedbash
undefinedLaunch by bundle ID
通过Bundle ID启动应用
xcrun simctl launch booted com.example.MyApp
xcrun simctl launch booted com.example.MyApp
Launch and stream stdout/stderr to the terminal
启动应用并将stdout/stderr流式传输到终端
xcrun simctl launch --console booted com.example.MyApp
xcrun simctl launch --console booted com.example.MyApp
Pass launch arguments
传递启动参数
xcrun simctl launch booted com.example.MyApp --reset-onboarding -AppleLanguages "(fr)"
xcrun simctl launch booted com.example.MyApp --reset-onboarding -AppleLanguages "(fr)"
Terminate a running app
终止运行中的应用
xcrun simctl terminate booted com.example.MyApp
`--console` is useful for debugging — it shows `print()` and `os_log` output directly in the terminal.xcrun simctl terminate booted com.example.MyApp
`--console`对调试很有用——它会将`print()`和`os_log`输出直接显示在终端中。App Container Paths
应用容器路径
bash
undefinedbash
undefinedApp bundle location
应用包位置
xcrun simctl get_app_container booted com.example.MyApp app
xcrun simctl get_app_container booted com.example.MyApp app
Data container (Documents, Library, tmp)
数据容器(Documents、Library、tmp)
xcrun simctl get_app_container booted com.example.MyApp data
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
Use these paths to inspect sandboxed files, databases, or UserDefaults during debugging.xcrun simctl get_app_container booted com.example.MyApp group.com.example.shared
调试期间,可使用这些路径检查沙盒文件、数据库或UserDefaults。Testing Workflows
测试工作流
Push Notification Simulation
推送通知模拟
Create a JSON payload file:
json
{
"aps": {
"alert": {
"title": "New Message",
"body": "You have a new message from Alice"
},
"badge": 3,
"sound": "default"
},
"customKey": "customValue"
}Send it to the Simulator:
bash
undefined创建JSON载荷文件:
json
{
"aps": {
"alert": {
"title": "New Message",
"body": "You have a new message from Alice"
},
"badge": 3,
"sound": "default"
},
"customKey": "customValue"
}将其发送到模拟器:
bash
undefinedSend push payload from file
从文件发送推送载荷
xcrun simctl push booted com.example.MyApp payload.json
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 -
This simulates local delivery only — no APNs connection is involved. Use this to test payload handling, notification display, and notification actions. Always verify on a real device before shipping to confirm APNs delivery works end to end.echo '{"aps":{"alert":"Quick test"}}' | xcrun simctl push booted com.example.MyApp -
这仅模拟本地交付——不涉及APNs连接。可用于测试载荷处理、通知显示和通知操作。发布前务必在真实设备上验证,以确认APNs端到端交付正常工作。Location Simulation
位置模拟
bash
undefinedbash
undefinedSet a fixed coordinate (latitude, longitude)
设置固定坐标(纬度,经度)
xcrun simctl location booted set 37.3349,-122.0090
xcrun simctl location booted set 37.3349,-122.0090
List available predefined scenarios
列出可用的预定义场景
xcrun simctl location booted list
xcrun simctl location booted list
Run a predefined scenario
运行预定义场景
xcrun simctl location booted run "City Run"
xcrun simctl location booted run "City Run"
Clear the simulated location
清除模拟位置
xcrun simctl location booted clear
The `run` subcommand accepts predefined scenario names (e.g., "City Run", "Freeway Drive"), not GPX file paths. Use Xcode's Debug > Simulate Location menu for GPX-based routes.
Location simulation affects all apps using Core Location on the booted device. Clear the location when done to avoid unexpected test results.xcrun simctl location booted clear
`run`子命令接受预定义场景名称(例如"City Run"、"Freeway Drive"),而非GPX文件路径。如需基于GPX的路线,请使用Xcode的Debug > Simulate Location菜单。
位置模拟会影响已启动设备上所有使用Core Location的应用。完成后请清除位置,避免出现意外测试结果。Privacy Permissions
隐私权限
bash
undefinedbash
undefinedGrant a permission
授予权限
xcrun simctl privacy booted grant photos com.example.MyApp
xcrun simctl privacy booted grant photos com.example.MyApp
Revoke a permission
撤销权限
xcrun simctl privacy booted revoke microphone com.example.MyApp
xcrun simctl privacy booted revoke microphone com.example.MyApp
Reset all permissions for the app
重置应用的所有权限
xcrun simctl privacy booted reset all com.example.MyApp
Common service names: `photos`, `microphone`, `contacts`, `calendar`, `reminders`, `location`, `location-always`, `motion`, `siri`. See [references/simctl-commands.md](references/simctl-commands.md) for the full list.
Pre-granting permissions in CI avoids system permission dialogs that block automated test runs.xcrun simctl privacy booted reset all com.example.MyApp
常见服务名称:`photos`、`microphone`、`contacts`、`calendar`、`reminders`、`location`、`location-always`、`motion`、`siri`。完整列表请查看[references/simctl-commands.md](references/simctl-commands.md)。
在CI中预先授予权限可避免系统权限弹窗阻塞自动化测试运行。Deep Links and URLs
深度链接与URL
bash
undefinedbash
undefinedOpen a URL (triggers universal links or custom URL schemes)
打开URL(触发通用链接或自定义URL scheme)
xcrun simctl openurl booted "https://example.com/product/123"
xcrun simctl openurl booted "https://example.com/product/123"
Custom URL scheme
自定义URL scheme
xcrun simctl openurl booted "myapp://settings/notifications"
For universal links, the app's associated domains entitlement must be configured. The Simulator uses the `apple-app-site-association` file from the domain.xcrun simctl openurl booted "myapp://settings/notifications"
对于通用链接,必须配置应用的关联域权限。模拟器会使用域名下的`apple-app-site-association`文件。Status Bar Overrides
状态栏覆盖
bash
undefinedbash
undefinedSet 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 ""
--time "9:41"
--batteryState charged
--batteryLevel 100
--cellularMode active
--cellularBars 4
--wifiBars 3
--operatorName ""
xcrun simctl status_bar booted override
--time "9:41"
--batteryState charged
--batteryLevel 100
--cellularMode active
--cellularBars 4
--wifiBars 3
--operatorName ""
--time "9:41"
--batteryState charged
--batteryLevel 100
--cellularMode active
--cellularBars 4
--wifiBars 3
--operatorName ""
Clear all overrides
清除所有覆盖设置
xcrun simctl status_bar booted clear
Use status bar overrides to produce consistent App Store screenshots. Always clear overrides after capturing to avoid confusing other testing.xcrun simctl status_bar booted clear
使用状态栏覆盖可生成一致的App Store截图。捕获完成后务必清除覆盖设置,避免干扰其他测试。Screenshot and Video Recording
截图与录屏
bash
undefinedbash
undefinedCapture a screenshot
捕获截图
xcrun simctl io booted screenshot screenshot.png
xcrun simctl io booted screenshot screenshot.png
Record video (press Ctrl+C to stop)
录制视频(按Ctrl+C停止)
xcrun simctl io booted recordVideo recording.mov
xcrun simctl io booted recordVideo recording.mov
Screenshot with specific display mask
带特定显示遮罩的截图
xcrun simctl io booted screenshot --mask black screenshot.png
`--mask` options: `ignored` (default, no mask), `alpha` (transparent corners), `black` (black corners). Use `alpha` or `black` when capturing screenshots that show the device shape. The `alpha` mask is only supported for screenshots — video recording falls back to `black`.
Video recording continues until the process receives SIGINT (Ctrl+C). The recording is saved only after stopping — killing the process with SIGKILL loses the file.xcrun simctl io booted screenshot --mask black screenshot.png
`--mask`选项:`ignored`(默认,无遮罩)、`alpha`(透明边角)、`black`(黑色边角)。捕获显示设备外形的截图时,请使用`alpha`或`black`。`alpha`遮罩仅支持截图——录屏会 fallback 到`black`。
视频录制会持续到进程收到SIGINT(Ctrl+C)。仅在停止后才会保存录制内容——使用SIGKILL终止进程会丢失文件。Log Streaming
日志流
Basic Log Stream
基础日志流
bash
undefinedbash
undefinedStream all logs at debug level and above
流式传输所有调试级别及以上的日志
xcrun simctl spawn booted log stream --level debug
xcrun simctl spawn booted log stream --level debug
Filter by subsystem
按子系统过滤
xcrun simctl spawn booted log stream --level debug
--predicate 'subsystem == "com.example.app"'
--predicate 'subsystem == "com.example.app"'
xcrun simctl spawn booted log stream --level debug
--predicate 'subsystem == "com.example.app"'
--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"'
--predicate 'subsystem == "com.example.app" AND category == "networking"'
xcrun simctl spawn booted log stream --level debug
--predicate 'subsystem == "com.example.app" AND category == "networking"'
--predicate 'subsystem == "com.example.app" AND category == "networking"'
Filter by process name
按进程名称过滤
xcrun simctl spawn booted log stream
--predicate 'process == "MyApp"'
--predicate 'process == "MyApp"'
undefinedxcrun simctl spawn booted log stream
--predicate 'process == "MyApp"'
--predicate 'process == "MyApp"'
undefinedCombining with os.Logger
与os.Logger结合使用
Design subsystems and categories for filterability:
swift
import os
let networkLogger = Logger(subsystem: "com.example.app", category: "networking")
let uiLogger = Logger(subsystem: "com.example.app", category: "ui")
func fetchData() async throws -> Data {
networkLogger.debug("Starting request to /api/data")
let (data, response) = try await URLSession.shared.data(from: url)
networkLogger.info("Received \(data.count) bytes, status: \((response as? HTTPURLResponse)?.statusCode ?? 0)")
return data
}Then filter the log stream to see only networking output:
bash
xcrun simctl spawn booted log stream --level debug \
--predicate 'subsystem == "com.example.app" AND category == "networking"'设计可过滤的子系统和类别:
swift
import os
let networkLogger = Logger(subsystem: "com.example.app", category: "networking")
let uiLogger = Logger(subsystem: "com.example.app", category: "ui")
func fetchData() async throws -> Data {
networkLogger.debug("Starting request to /api/data")
let (data, response) = try await URLSession.shared.data(from: url)
networkLogger.info("Received \(data.count) bytes, status: \((response as? HTTPURLResponse)?.statusCode ?? 0)")
return data
}然后过滤日志流以仅查看网络输出:
bash
xcrun simctl spawn booted log stream --level debug \
--predicate 'subsystem == "com.example.app" AND category == "networking"'Compile-Time Simulator Detection
编译时模拟器检测
Use to exclude code that cannot run in the Simulator:
#if targetEnvironment(simulator)swift
func registerForPush() {
#if targetEnvironment(simulator)
logger.info("Skipping APNs registration — running in Simulator")
#else
UIApplication.shared.registerForRemoteNotifications()
#endif
}Runtime detection via environment variables:
swift
var isSimulator: Bool {
ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
}Prefer compile-time checks () over runtime checks. The compiler strips excluded code entirely, preventing linker errors from unavailable symbols.
#if targetEnvironment(simulator)使用排除无法在模拟器中运行的代码:
#if targetEnvironment(simulator)swift
func registerForPush() {
#if targetEnvironment(simulator)
logger.info("Skipping APNs registration — running in Simulator")
#else
UIApplication.shared.registerForRemoteNotifications()
#endif
}通过环境变量进行运行时检测:
swift
var isSimulator: Bool {
ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
}优先使用编译时检查()而非运行时检查。编译器会完全剥离被排除的代码,避免因不可用符号导致链接错误。
#if targetEnvironment(simulator)Simulator Limitations
模拟器限制
| Capability | Simulator Support |
|---|---|
| APNs push delivery | No — use |
| Metal GPU family parity | Partial — host GPU, not device GPU; some shaders differ |
| Camera hardware | No — use photo library injection or mock |
| Microphone | No hardware mic — audio input is routed from Mac microphone |
| Secure Enclave | No — |
| App Attest (DCAppAttestService) | No — |
| DockKit motor control | No — no physical accessory connection |
| Accelerometer / Gyroscope | No real sensors — use |
| Barometer | No |
| NFC (Core NFC) | No |
| Bluetooth (Core Bluetooth) | No — use a real device for BLE testing |
| CarPlay hardware | No — use the separate CarPlay Simulator companion app |
| Face ID / Touch ID hardware | No hardware — use Features > Face ID / Touch ID menu in Simulator |
| Cellular network conditions | No — use Network Link Conditioner on Mac |
| 功能 | 模拟器支持情况 |
|---|---|
| APNs推送交付 | 不支持 — 使用 |
| Metal GPU系列一致性 | 部分支持 — 使用主机GPU而非设备GPU;部分着色器存在差异 |
| 摄像头硬件 | 不支持 — 使用照片库注入或模拟 |
| 麦克风 | 无硬件麦克风 — 音频输入来自Mac麦克风 |
| 安全隔区 | 不支持 — |
| App Attest(DCAppAttestService) | 不支持 — |
| DockKit电机控制 | 不支持 — 无物理配件连接 |
| 加速度计/陀螺仪 | 无真实传感器 — 在Xcode中使用 |
| 气压计 | 不支持 |
| NFC(Core NFC) | 不支持 |
| 蓝牙(Core Bluetooth) | 不支持 — 使用真实设备进行BLE测试 |
| CarPlay硬件 | 不支持 — 使用单独的CarPlay Simulator配套应用 |
| Face ID/Touch ID硬件 | 无硬件 — 使用模拟器中的Features > Face ID / Touch ID菜单 |
| 蜂窝网络条件 | 不支持 — 在Mac上使用Network Link Conditioner |
Common Mistakes
常见错误
DON'T: Hardcode simulator UDIDs in scripts
不要:在脚本中硬编码模拟器UDID
UDIDs change when simulators are deleted and recreated. Hardcoded values break on other machines and CI.
bash
undefined删除并重新创建模拟器时,UDID会更改。硬编码的值会在其他机器和CI环境中失效。
bash
undefinedWRONG — hardcoded UDID
错误示例 — 硬编码UDID
xcrun simctl boot "A1B2C3D4-E5F6-7890-ABCD-EF1234567890"
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"
jq -r '.devices["com.apple.CoreSimulator.SimRuntime.iOS-18-4"][] | select(.name == "iPhone 16 Pro") | .udid') xcrun simctl boot "$UDID"
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"
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
正确示例 — 当仅有一个模拟器运行时使用"booted"
xcrun simctl install booted MyApp.app
undefinedxcrun simctl install booted MyApp.app
undefinedDON'T: Install or launch on a shutdown simulator
不要:在已关闭的模拟器上安装或启动应用
simctl installsimctl launchbash
undefinedsimctl installsimctl launchbash
undefinedWRONG — device is not booted
错误示例 — 设备未启动
xcrun simctl install <UDID> MyApp.app # fails
xcrun simctl install <UDID> MyApp.app # 执行失败
CORRECT — boot first, then install
正确示例 — 先启动设备,再安装
xcrun simctl boot <UDID>
xcrun simctl install <UDID> MyApp.app
xcrun simctl launch <UDID> com.example.MyApp
undefinedxcrun simctl boot <UDID>
xcrun simctl install <UDID> MyApp.app
xcrun simctl launch <UDID> com.example.MyApp
undefinedDON'T: Leave zombie simulators running in CI
不要:在CI中遗留僵尸模拟器运行
Each booted simulator consumes memory and CPU. CI pipelines that create simulators without cleanup accumulate zombie devices.
bash
undefined每个已启动的模拟器都会占用内存和CPU。创建模拟器但不清理的CI流水线会累积僵尸设备。
bash
undefinedWRONG — CI script creates and boots but never cleans up
错误示例 — CI脚本创建并启动设备但从不清理
xcrun simctl create "CI Phone" "iPhone 16 Pro" "com.apple.CoreSimulator.SimRuntime.iOS-18-4"
xcrun simctl boot "$UDID"
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
正确示例 — 在CI清理阶段始终进行清理
cleanup() {
xcrun simctl shutdown all
xcrun simctl delete "$UDID"
}
trap cleanup EXIT
undefinedcleanup() {
xcrun simctl shutdown all
xcrun simctl delete "$UDID"
}
trap cleanup EXIT
undefinedDON'T: Assume simctl push validates APNs delivery
不要:假设simctl push能验证APNs交付
simctl pushbash
undefinedsimctl pushbash
undefinedWRONG — only testing with simctl, shipping without real device testing
错误示例 — 仅使用simctl测试,未在真实设备上测试就发布
xcrun simctl push booted com.example.MyApp payload.json
xcrun simctl push booted com.example.MyApp payload.json
"Push works!" — no, it only proves the app handles the payload
"推送正常!" — 不,这仅证明应用能处理载荷
CORRECT — use simctl for development iteration, then verify end-to-end on a real device
正确示例 — 开发阶段使用simctl快速迭代,发布前在真实设备上验证端到端流程
1. simctl push during development for fast iteration
1. 开发期间使用simctl push快速迭代
2. Real device + APNs sandbox for integration testing before release
2. 发布前使用真实设备 + APNs沙箱进行集成测试
undefinedundefinedDON'T: Keep retrying boot on a stuck simulator
不要:在卡住的模拟器上反复尝试启动
A simulator stuck in the "Booting" state will not recover by retrying . The underlying CoreSimulator state is corrupted.
bootbash
undefined处于"Booting"状态的模拟器不会通过反复执行命令恢复。底层CoreSimulator状态已损坏。
bootbash
undefinedWRONG — 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
xcrun simctl boot "$UDID" # "Unable to boot device in current state: Booting"
xcrun simctl boot "$UDID" # 同样的错误,无限循环
CORRECT — shut down, erase, and retry
正确示例 — 关闭、擦除后重试
xcrun simctl shutdown "$UDID"
xcrun simctl erase "$UDID"
xcrun simctl boot "$UDID"
xcrun simctl shutdown "$UDID"
xcrun simctl erase "$UDID"
xcrun simctl boot "$UDID"
If that fails, reset CoreSimulator entirely
如果仍失败,完全重置CoreSimulator
xcrun simctl shutdown all
xcrun simctl erase all
xcrun simctl shutdown all
xcrun simctl erase all
Last resort: rm -rf ~/Library/Developer/CoreSimulator/Caches
最后手段:rm -rf ~/Library/Developer/CoreSimulator/Caches
undefinedundefinedReview Checklist
检查清单
- Simulator devices created with explicit device type and runtime identifiers
- Scripts use or parsed UDID from JSON output, not hardcoded values
booted - Push notification payloads tested via during development
simctl push - Push notification delivery verified on a real device before release
- Location simulation tested with both fixed coordinates and predefined scenarios
- Privacy permissions pre-granted in CI to avoid blocking dialogs
- guards around APIs unavailable in Simulator
#if targetEnvironment(simulator) - Status bar overrides cleared after capturing screenshots
- CI pipelines shut down and delete simulators in teardown
- Log streaming configured with subsystem/category predicates for focused debugging
- App container paths used for inspecting sandboxed data during debugging
- 使用明确的设备类型和运行时标识符创建模拟器设备
- 脚本使用或从JSON输出解析的UDID,而非硬编码值
booted - 开发阶段通过测试推送通知载荷
simctl push - 发布前在真实设备上验证推送通知交付
- 使用固定坐标和预定义场景测试位置模拟
- 在CI中预先授予权限以避免阻塞弹窗
- 对模拟器中不可用的API使用进行防护
#if targetEnvironment(simulator) - 捕获截图后清除状态栏覆盖设置
- CI流水线在清理阶段关闭并删除模拟器
- 配置日志流时使用子系统/类别谓词进行聚焦调试
- 调试期间使用应用容器路径检查沙盒数据
References
参考资料
- Running your app in Simulator or on a device
- Downloading and installing additional Xcode components
- simctl command reference: references/simctl-commands.md
- 在模拟器或设备上运行应用
- 下载并安装额外的Xcode组件
- simctl命令参考:references/simctl-commands.md