ios-simulator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

iOS Simulator

iOS Simulator

Manage iOS Simulator devices and test app behavior from the command line using
xcrun simctl
. Covers the full device lifecycle, app deployment, push and location simulation, permission control, screenshot and video recording, log streaming, and compile-time simulator detection.
For the complete subcommand reference with all flags and options, see references/simctl-commands.md.
使用
xcrun simctl
从命令行管理iOS Simulator设备并测试应用行为。涵盖完整的设备生命周期、应用部署、推送与位置模拟、权限控制、截图与录屏、日志流以及编译时模拟器检测。
如需包含所有标志和选项的完整子命令参考,请查看references/simctl-commands.md

Contents

目录

Device Lifecycle

设备生命周期

Listing Devices and Runtimes

列出设备与运行时

bash
undefined
bash
undefined

List 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
undefined
bash
undefined

Find 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
undefined
bash
undefined

Boot 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 booted
If multiple simulators are booted,
booted
picks one of them non-deterministically. Prefer explicit UDIDs when running parallel simulators.
xcrun simctl shutdown all

当仅有一个模拟器运行时,可使用`booted`作为UDID的简写:

```bash
xcrun simctl shutdown booted
如果多个模拟器已启动,
booted
会非确定性地选择其中一个。运行并行模拟器时,建议使用明确的UDID。

App Install and Launch

应用安装与启动

Installing an App

安装应用

bash
undefined
bash
undefined

Build for simulator first

先为模拟器构建应用

xcodebuild 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/

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
undefined
bash
undefined

Launch 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
undefined
bash
undefined

App 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
undefined

Send 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
undefined
bash
undefined

Set 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
undefined
bash
undefined

Grant 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
undefined
bash
undefined

Open 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
undefined
bash
undefined

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 ""
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

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
undefined
bash
undefined

Capture 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
undefined
bash
undefined

Stream 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"'
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"'
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"'
undefined
xcrun simctl spawn booted log stream
--predicate 'process == "MyApp"'
undefined

Combining 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
#if targetEnvironment(simulator)
to exclude code that cannot run in the 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 (
#if targetEnvironment(simulator)
) over runtime checks. The compiler strips excluded code entirely, preventing linker errors from unavailable symbols.
使用
#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

模拟器限制

CapabilitySimulator Support
APNs push deliveryNo — use
simctl push
for local simulation
Metal GPU family parityPartial — host GPU, not device GPU; some shaders differ
Camera hardwareNo — use photo library injection or mock
AVCaptureSession
MicrophoneNo hardware mic — audio input is routed from Mac microphone
Secure EnclaveNo —
kSecAttrTokenIDSecureEnclave
operations fail
App Attest (DCAppAttestService)No —
isSupported
returns
false
DockKit motor controlNo — no physical accessory connection
Accelerometer / GyroscopeNo real sensors — use
CMMotionManager
simulation in Xcode
BarometerNo
NFC (Core NFC)No
Bluetooth (Core Bluetooth)No — use a real device for BLE testing
CarPlay hardwareNo — use the separate CarPlay Simulator companion app
Face ID / Touch ID hardwareNo hardware — use Features > Face ID / Touch ID menu in Simulator
Cellular network conditionsNo — use Network Link Conditioner on Mac
功能模拟器支持情况
APNs推送交付不支持 — 使用
simctl push
进行本地模拟
Metal GPU系列一致性部分支持 — 使用主机GPU而非设备GPU;部分着色器存在差异
摄像头硬件不支持 — 使用照片库注入或模拟
AVCaptureSession
麦克风无硬件麦克风 — 音频输入来自Mac麦克风
安全隔区不支持 —
kSecAttrTokenIDSecureEnclave
操作会失败
App Attest(DCAppAttestService)不支持 —
isSupported
返回
false
DockKit电机控制不支持 — 无物理配件连接
加速度计/陀螺仪无真实传感器 — 在Xcode中使用
CMMotionManager
模拟
气压计不支持
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
undefined

WRONG — 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"
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

正确示例 — 当仅有一个模拟器运行时使用"booted"

xcrun simctl install booted MyApp.app
undefined
xcrun simctl install booted MyApp.app
undefined

DON'T: Install or launch on a shutdown simulator

不要:在已关闭的模拟器上安装或启动应用

simctl install
and
simctl launch
require a booted device. They fail silently or with an unhelpful error on a shutdown device.
bash
undefined
simctl install
simctl launch
要求设备处于启动状态。在已关闭的设备上执行这些命令会静默失败或返回无意义的错误。
bash
undefined

WRONG — 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
undefined
xcrun simctl boot <UDID> xcrun simctl install <UDID> MyApp.app xcrun simctl launch <UDID> com.example.MyApp
undefined

DON'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
undefined

WRONG — 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
undefined
cleanup() { xcrun simctl shutdown all xcrun simctl delete "$UDID" } trap cleanup EXIT
undefined

DON'T: Assume simctl push validates APNs delivery

不要:假设simctl push能验证APNs交付

simctl push
bypasses the entire APNs infrastructure. It tests payload parsing and notification UI, not token registration, entitlements, or server-side delivery.
bash
undefined
simctl push
绕过了整个APNs基础设施。它仅测试载荷解析和通知UI,不测试令牌注册、权限或服务器端交付。
bash
undefined

WRONG — 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沙箱进行集成测试

undefined
undefined

DON'T: Keep retrying boot on a stuck simulator

不要:在卡住的模拟器上反复尝试启动

A simulator stuck in the "Booting" state will not recover by retrying
boot
. The underlying CoreSimulator state is corrupted.
bash
undefined
处于"Booting"状态的模拟器不会通过反复执行
boot
命令恢复。底层CoreSimulator状态已损坏。
bash
undefined

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
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

undefined
undefined

Review Checklist

检查清单

  • Simulator devices created with explicit device type and runtime identifiers
  • Scripts use
    booted
    or parsed UDID from JSON output, not hardcoded values
  • Push notification payloads tested via
    simctl push
    during development
  • 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
  • #if targetEnvironment(simulator)
    guards around APIs unavailable in 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
  • 使用明确的设备类型和运行时标识符创建模拟器设备
  • 脚本使用
    booted
    或从JSON输出解析的UDID,而非硬编码值
  • 开发阶段通过
    simctl push
    测试推送通知载荷
  • 发布前在真实设备上验证推送通知交付
  • 使用固定坐标和预定义场景测试位置模拟
  • 在CI中预先授予权限以避免阻塞弹窗
  • 对模拟器中不可用的API使用
    #if targetEnvironment(simulator)
    进行防护
  • 捕获截图后清除状态栏覆盖设置
  • CI流水线在清理阶段关闭并删除模拟器
  • 配置日志流时使用子系统/类别谓词进行聚焦调试
  • 调试期间使用应用容器路径检查沙盒数据

References

参考资料