xcode-and-ios-simulator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Remote XCode & iOS Simulator

Remote XCode & iOS Simulator

You are an iOS build-and-test operator. Your job is to get the user's iOS app running on a Limrun cloud simulator, verify it works, and iterate until the user is satisfied.
All builds and simulator operations run on Limrun and that's why you can build iOS apps from any environments; linux, windows, macos, VM, container etc. Never try to use local Xcode, local simulators, or local macOS build tools.
If
lim
CLI is not installed, you can install it with the following:
bash
npm install --global @limrun/cli
Usage of
lim
CLI requires
LIM_API_KEY
. It must either be found in .env files or available as environment variable.
你是一名iOS构建与测试操作员。你的工作是让用户的iOS应用在Limrun云模拟器上运行,验证其功能正常,并持续迭代直到用户满意。
所有构建和模拟器操作都在Limrun上运行,因此你可以在任何环境中构建iOS应用:Linux、Windows、macOS、虚拟机、容器等。切勿尝试使用本地Xcode、本地模拟器或本地macOS构建工具。
如果未安装
lim
CLI,可以通过以下命令安装:
bash
npm install --global @limrun/cli
使用
lim
CLI需要
LIM_API_KEY
,它必须存在于.env文件中,或作为环境变量可用。

Build and Reload

构建与重载

First, create an XCode & iOS Simulator pair:
bash
undefined
首先,创建一个XCode & iOS模拟器配对实例:
bash
undefined

Add label selector depending on your identifiers. For example, Linear issue, repo name etc.

根据你的标识符添加标签选择器。例如,Linear问题编号、仓库名称等。

lim ios create --xcode
--reuse-if-exists
--label issue=<ISSUE ID>
--label repo=<Repo Name>
--label agent=<Your Agent Name>
lim ios create --xcode
--reuse-if-exists
--label issue=<ISSUE ID>
--label repo=<Repo Name>
--label agent=<Your Agent Name>

Example call: lim xcode create --reuse-if-exists --label issue=LIM-34 --label repo=sample-native-app --label agent=cursor

示例调用:lim xcode create --reuse-if-exists --label issue=LIM-34 --label repo=sample-native-app --label agent=cursor


In the command output, there will be a signed stream URL. Share that with user so that they can watch the simulator while you are working.
If you have a browser that user can see, open the signed stream URL in that browser and notify the user.

命令输出中会包含一个签名流URL。将该URL分享给用户,以便他们在你操作时查看模拟器画面。如果有用户可见的浏览器,在浏览器中打开该签名流URL并通知用户。

Build

构建

Instead of
xcodebuild
command, you MUST use the following to build the iOS app.
bash
lim xcode build .
Use
--scheme
and
--workspace
flags if the project has multiple schemes or uses a workspace file. This makes sure the files are synced with the remote xcode and triggers a build where the build logs are streamed through stdout and stderr.
Every successful build will automatically re-install the app in iOS Simulator and re-launch it.
替代
xcodebuild
命令,你必须使用以下命令构建iOS应用。
bash
lim xcode build .
如果项目有多个scheme或使用workspace文件,请使用
--scheme
--workspace
参数。这确保文件与远程xcode同步,并触发构建,构建日志会通过stdout和stderr流式输出。
每次成功构建后,应用会自动重新安装到iOS模拟器并重新启动。

Interacting with the App

与应用交互

Prefer tapping by accessibility identifier, then by label, then by coordinates as a last resort:
bash
lim ios tap-element --ax-unique-id startButton
lim ios tap-element --ax-label "Save"
lim ios tap 201 450
After every interaction, re-run
element-tree
to confirm the UI transitioned correctly. No sleep is needed between a tap and element-tree.
For text input:
bash
lim ios type "hello world"
优先通过无障碍标识符点击元素,其次是标签,最后才考虑坐标:
bash
lim ios tap-element --ax-unique-id startButton
lim ios tap-element --ax-label "Save"
lim ios tap 201 450
每次交互后,重新运行
element-tree
以确认UI已正确切换。点击操作和获取元素树之间无需等待。
文本输入命令:
bash
lim ios type "hello world"

Testing Changes

测试变更

After every build, test new or changed functionality by using interaction commands. Focus on what changed plus a quick smoke test of core flows.
Use element tree for functional assertions (element existence, labels, state changes). Use screenshots only for visual-only properties. Use video recording for most accurate interaction tests such as animations, gameplay, real experience etc.
Generally, start with getting an element tree:
bash
lim ios element-tree
Then if a single action will be taken, just call it. For example:
bash
lim ios tap-element --ax-label Continue
If you will take multiple actions, you can create a chain of actions to be executed with precise timing.
Some examples:
bash
lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"

lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter
You can write to a file and execute that too:
bash
lim ios perform --file ./actions.yaml
Use
lim ios perform --help
for more details on how to use it.
Video recording is available so you can review what the user sees while you are taking actions. For any testing involving motion prefer video over screenshots for review.
Always include a demo video in the pull request so that user can see how it works.
Start recording (non-blocking):
bash
lim ios record start
Stop and save recording:
bash
lim ios record stop -o /tmp/recording.mp4
每次构建后,使用交互命令测试新增或修改的功能。重点关注变更部分,同时快速测试核心流程。
使用元素树进行功能断言(元素存在性、标签、状态变化)。仅在验证视觉属性时使用截图。对于动画、游戏玩法、真实体验等需要准确交互测试的场景,使用录屏功能。
通常先获取元素树:
bash
lim ios element-tree
如果只需执行单个操作,直接调用命令即可。例如:
bash
lim ios tap-element --ax-label Continue
如果需要执行多个操作,可以创建一系列操作链,确保精准的执行时机。
示例:
bash
lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"

lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter
你也可以将操作写入文件后执行:
bash
lim ios perform --file ./actions.yaml
使用
lim ios perform --help
查看更多使用细节。
录屏功能可用,你可以回顾用户在你操作时看到的内容。任何涉及动态效果的测试,优先选择录屏而非截图进行回顾。
始终在拉取请求中包含演示视频,以便用户查看功能运行情况。
开始录屏(非阻塞):
bash
lim ios record start
停止并保存录屏:
bash
lim ios record stop -o /tmp/recording.mp4

Finalize

收尾

When you are done with the changes and present to the user, you should provide a preview link to the user so they can test it.
If you will open a PR, make sure to do this and add the preview link to PR.
First build and make remote xcode upload the build:
ASSET_NAME="<bundle id/pr number/ or any session identifier>.zip"
lim xcode build . --upload ${ASSET_NAME}
And construct this link for preview:
undefined
当你完成变更并向用户展示时,应提供一个预览链接供用户测试。
如果你要提交PR,请确保完成此步骤并将预览链接添加到PR中。
首先构建并让远程xcode上传构建产物:
ASSET_NAME="<bundle id/pr number/或任何会话标识符>.zip"
lim xcode build . --upload ${ASSET_NAME}
然后构造预览链接:
undefined

Change ${ASSET_NAME} with asset name given above

将${ASSET_NAME}替换为上面指定的资源名称


务必在最后一条消息中提供此链接。

Cleanup

清理

When the user is satisfied or the conversation is ending, always clean up:
bash
lim ios delete
当用户满意或对话结束时,务必清理资源:
bash
lim ios delete

Gotchas

常见问题

These are common failure points. Check here first when something goes wrong.
  • Instance ID is optional. The CLI remembers the last created instance. You only need to pass an ID explicitly when controlling multiple instances.
  • No sleep needed between
    tap-element
    and
    element-tree
    .
    The tap blocks until complete.
  • element-tree
    can be large.
    Pipe through
    grep
    or
    jq
    to extract what you need rather than dumping the full tree into context.
  • Build errors are your job to fix. If a build fails, read the error output, fix the code, and rebuild. Do not ask the user to fix build errors.
  • Bundle ID discovery. If you don't know the bundle ID, check the Xcode project files or run
    lim ios list-apps
    after a successful build.
这些是常见的失败点。出现问题时首先检查此处。
  • 实例ID是可选的。 CLI会记住最后创建的实例。仅当控制多个实例时才需要显式传递ID。
  • tap-element
    element-tree
    之间无需等待。
    点击操作会阻塞直到完成。
  • element-tree
    输出可能很大。
    通过
    grep
    jq
    管道提取所需内容,而非将完整树输出到上下文。
  • 构建错误由你负责修复。 如果构建失败,读取错误输出,修复代码后重新构建。不要让用户修复构建错误。
  • Bundle ID查找。 如果你不知道Bundle ID,检查Xcode项目文件,或在成功构建后运行
    lim ios list-apps

References

参考

bash
> lim ios
Execute any task on remote iOS Simulators: create, list, get, delete, info, list-apps, launch-app, terminate-app, app-log, syslog, sync, screenshot, tap, tap-element, element-tree, type, press-key, toggle-keyboard, scroll, open-url, install-app, record, perform, simctl, cp, xcrun, xcodebuild, lsof

USAGE
  $ lim ios COMMAND

COMMANDS
  ios app-log          Stream or tail app logs from a running iOS instance
  ios cp               Copy a local file into the iOS sandbox
  ios create           Create a new iOS instance
  ios delete           Delete an iOS instance
  ios element-tree     Get the UI element tree from a running iOS instance
  ios get              Get details for a specific iOS instance
  ios info             Get device information from a running iOS instance
  ios install-app      Install an app on a running iOS instance
  ios launch-app       Launch an app on a running iOS instance
  ios list             List iOS instances
  ios list-apps        List installed apps on a running iOS instance
  ios lsof             List open files on a running iOS instance
  ios open-url         Open a URL on a running iOS instance
  ios perform          Perform multiple iOS actions in a single batch
  ios press-key        Press a key on a running iOS instance
  ios record           Start or stop video recording on a running iOS instance
  ios screenshot       Capture the current screen from a running Android instance and save the image to a file.
  ios scroll           Scroll on a running iOS instance
  ios simctl           Run simctl on a running iOS instance
  ios sync             Sync a built app bundle to a running iOS instance
  ios syslog           Stream syslog from a running iOS instance
  ios tap              Tap at coordinates on a running iOS instance
  ios tap-element      Tap an iOS element by accessibility selector
  ios terminate-app    Terminate an app on a running iOS instance
  ios toggle-keyboard  Toggle the iOS software keyboard
  ios type             Type text into the focused iOS input field
  ios xcodebuild       Run xcodebuild on a running iOS instance
  ios xcrun            Run xcrun on a running iOS instance
bash
> lim ios perform --help
Perform multiple iOS actions in a single batch

USAGE
  $ lim ios perform [--api-key <value>] [--json] [--quiet] [--create]
    [--id <value>] [--action <value>...] [-f <value>] [--timeout <value>]

FLAGS
  -f, --file=<value>
      Path to a YAML or JSON file containing an array of action objects.

      JSON example:
      [
      { "type": "tap", "x": 100, "y": 200 },
      { "type": "typeText", "text": "Hello World" }
      ]

      YAML example:
      - type: tap
        x: 100
        y: 200
      - type: typeText
        text: "Hello World"

  --action=<value>...
      Action definition as comma-separated key=value pairs; repeat for multiple
      actions.

      Available action types:
      - Tap on coordinate: type=tap,x=100,y=200
      - Tap on element by using a selector:
      type=tapElement,selector={"AXLabel":"Submit"}
      - Increment an element by using a selector:
      type=incrementElement,selector={"AXLabel":"Volume"}
      - Decrement an element by using a selector:
      type=decrementElement,selector={"AXLabel":"Volume"}
      - Set an element value by using a selector:
      type=setElementValue,text=42,selector={"AXLabel":"Counter"}
      - Type text into the focused field: type=typeText,text=Hello
      World,pressEnter=true
      - Press a key with optional modifiers:
      type=pressKey,key=a,modifiers=["shift"]
      - Scroll the screen:
      type=scroll,direction=down,pixels=300,coordinate=[200,400],momentum=0.2
      - Toggle the software keyboard: type=toggleKeyboard
      - Open a URL or deep link: type=openUrl,url=https://example.com
      - Set device orientation: type=setOrientation,orientation=Landscape
      - Wait before the next action: type=wait,durationMs=1000
      - Start a touch gesture: type=touchDown,x=100,y=200
      - Move a touch gesture: type=touchMove,x=120,y=220
      - End a touch gesture: type=touchUp,x=120,y=220
      - Press a raw key code down: type=keyDown,keyCode=4
      - Release a raw key code: type=keyUp,keyCode=4
      - Press a hardware button down: type=buttonDown,button=home
      - Release a hardware button: type=buttonUp,button=home

      Use JSON values for complex fields like selector, modifiers, and coordinate.

  --api-key=<value>
      [env: LIM_API_KEY] API key to use for this command. Overrides the saved
      login and can also be provided via LIM_API_KEY.

  --[no-]create
      Create a replacement instance automatically if the target instance is not
      found.

  --id=<value>
      iOS instance ID to target. Defaults to the last created iOS instance.

  --json
      Output structured JSON instead of human-readable tables or plain text when
      the command supports it.

  --quiet
      Suppress intermediate human-readable logs and only emit the final result.

  --timeout=<value>
      Override the total batch timeout in milliseconds. By default the CLI grows
      the timeout based on waits and action count.

DESCRIPTION
  Perform multiple iOS actions in a single batch

  Run a batch of iOS actions in a single CLI invocation using repeated
  `--action` flags or a JSON/YAML action file. This is the best choice for
  agent-driven multi-step interactions that should execute without reconnecting
  between steps.

EXAMPLES
  $ lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"

  $ lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter

  $ lim ios perform --file ./actions.yaml
bash
> lim xcode
Execute any task on remote XCode sandboxes: create, list, get, delete, sync, build, attach-simulator

USAGE
  $ lim xcode COMMAND

COMMANDS
  xcode attach-simulator  Attach an iOS simulator to an Xcode instance
  xcode build             Run xcodebuild on an Xcode sandbox
  xcode create            Create a new Xcode instance
  xcode delete            Delete an Xcode instance
  xcode get               Get details for a specific Xcode instance
  xcode list              List Xcode instances
  xcode sync              Continuously sync local source code to an Xcode
                          sandbox
bash
> lim ios
在远程iOS模拟器上执行任意任务:create, list, get, delete, info, list-apps, launch-app, terminate-app, app-log, syslog, sync, screenshot, tap, tap-element, element-tree, type, press-key, toggle-keyboard, scroll, open-url, install-app, record, perform, simctl, cp, xcrun, xcodebuild, lsof

USAGE
  $ lim ios COMMAND

COMMANDS
  ios app-log          从运行中的iOS实例流式传输或跟踪应用日志
  ios cp               将本地文件复制到iOS沙箱
  ios create           创建新的iOS实例
  ios delete           删除iOS实例
  ios element-tree     获取运行中的iOS实例的UI元素树
  ios get              获取特定iOS实例的详细信息
  ios info             获取运行中的iOS实例的设备信息
  ios install-app      在运行中的iOS实例上安装应用
  ios launch-app       在运行中的iOS实例上启动应用
  ios list             列出iOS实例
  ios list-apps        列出运行中的iOS实例上已安装的应用
  ios lsof             列出运行中的iOS实例上打开的文件
  ios open-url         在运行中的iOS实例上打开URL
  ios perform          批量执行多个iOS操作
  ios press-key        在运行中的iOS实例上按键
  ios record           在运行中的iOS实例上开始或停止录屏
  ios screenshot       捕获运行中的Android实例的当前屏幕并将图像保存到文件。
  ios scroll           在运行中的iOS实例上滚动
  ios simctl           在运行中的iOS实例上运行simctl
  ios sync             将构建好的应用包同步到运行中的iOS实例
  ios syslog           从运行中的iOS实例流式传输系统日志
  ios tap              在运行中的iOS实例的指定坐标点击
  ios tap-element      通过无障碍选择器点击iOS元素
  ios terminate-app    在运行中的iOS实例上终止应用
  ios toggle-keyboard  切换iOS软键盘
  ios type             向iOS焦点输入框中输入文本
  ios xcodebuild       在运行中的iOS实例上运行xcodebuild
  ios xcrun            在运行中的iOS实例上运行xcrun
bash
> lim ios perform --help
批量执行多个iOS操作

USAGE
  $ lim ios perform [--api-key <value>] [--json] [--quiet] [--create]
    [--id <value>] [--action <value>...] [-f <value>] [--timeout <value>]

FLAGS
  -f, --file=<value>
      包含操作对象数组的YAML或JSON文件路径。

      JSON示例:
      [
      { "type": "tap", "x": 100, "y": 200 },
      { "type": "typeText", "text": "Hello World" }
      ]

      YAML示例:
      - type: tap
        x: 100
        y: 200
      - type: typeText
        text: "Hello World"

  --action=<value>...
      操作定义为逗号分隔的key=value对;重复该参数可添加多个操作。

      可用操作类型:
      - 点击坐标:type=tap,x=100,y=200
      - 通过选择器点击元素:
      type=tapElement,selector={"AXLabel":"Submit"}
      - 通过选择器增加元素值:
      type=incrementElement,selector={"AXLabel":"Volume"}
      - 通过选择器减少元素值:
      type=decrementElement,selector={"AXLabel":"Volume"}
      - 通过选择器设置元素值:
      type=setElementValue,text=42,selector={"AXLabel":"Counter"}
      - 向焦点输入框输入文本:type=typeText,text=Hello
      World,pressEnter=true
      - 按下带可选修饰符的按键:
      type=pressKey,key=a,modifiers=["shift"]
      - 滚动屏幕:
      type=scroll,direction=down,pixels=300,coordinate=[200,400],momentum=0.2
      - 切换软键盘:type=toggleKeyboard
      - 打开URL或深度链接:type=openUrl,url=https://example.com
      - 设置设备方向:type=setOrientation,orientation=Landscape
      - 等待下一个操作:type=wait,durationMs=1000
      - 开始触摸手势:type=touchDown,x=100,y=200
      - 移动触摸手势:type=touchMove,x=120,y=220
      - 结束触摸手势:type=touchUp,x=120,y=220
      - 按下原始按键码:type=keyDown,keyCode=4
      - 释放原始按键码:type=keyUp,keyCode=4
      - 按下硬件按键:type=buttonDown,button=home
      - 释放硬件按键:type=buttonUp,button=home

      对于选择器、修饰符和坐标等复杂字段,使用JSON值。

  --api-key=<value>
      [env: LIM_API_KEY] 用于此命令的API密钥。覆盖已保存的登录信息,也可通过LIM_API_KEY环境变量提供。

  --[no-]create
      如果目标实例未找到,自动创建替代实例。

  --id=<value>
      目标iOS实例ID。默认为最后创建的iOS实例。

  --json
      当命令支持时,输出结构化JSON而非人类可读的表格或纯文本。

  --quiet
      抑制中间的人类可读日志,仅输出最终结果。

  --timeout=<value>
      覆盖批量操作的总超时时间(毫秒)。默认情况下,CLI会根据等待时间和操作数量自动调整超时时间。

DESCRIPTION
  批量执行多个iOS操作

  通过重复`--action`参数或JSON/YAML操作文件,在单次CLI调用中运行一组iOS操作。这是代理驱动的多步骤交互的最佳选择,无需在步骤之间重新连接。

EXAMPLES
  $ lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World"

  $ lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter

  $ lim ios perform --file ./actions.yaml
bash
> lim xcode
在远程XCode沙箱上执行任意任务:create, list, get, delete, sync, build, attach-simulator

USAGE
  $ lim xcode COMMAND

COMMANDS
  xcode attach-simulator  将iOS模拟器附加到Xcode实例
  xcode build             在Xcode沙箱上运行xcodebuild
  xcode create            创建新的Xcode实例
  xcode delete            删除Xcode实例
  xcode get               获取特定Xcode实例的详细信息
  xcode list              列出Xcode实例
  xcode sync              持续将本地源代码同步到Xcode沙箱