无极开物Docs

移动端 (iOS)

适用于本地栈的可选 iOS 开发及 dev-client 工作流。

本步骤为可选项。多数用户直接在移动端通过 Tailscale 访问 Web UI,或者将 Kaiwu 应用指向自托管中继即可(参见 App → Relay selection)。

前提条件(一次性配置)

  • 已安装 Xcode
  • 已安装 CocoaPods(brew install cocoapods)

支持的两种模式

  • 共享 dev-client 应用(推荐开发时使用):

    • 在手机上安装一个 hstack dev-client 应用。
    • 携带 --mobile 运行任意栈;扫描二维码即可在 dev-client 中打开该栈。
    • 各栈的认证与存储通过 EXPO_PUBLIC_HAPPY_STORAGE_SCOPE 相互隔离(历史遗留环境变量名;在栈模式下会自动设置)。
  • 单栈专属 “Release” 应用(推荐演示或需要严格隔离时使用):

    • 为每个栈安装独立的 iOS 应用(拥有唯一的 Bundle ID 与 Scheme)。
    • 各栈应用由 iOS 容器沙箱隔离,不存在 Token 冲突问题。

共享 dev-client 应用(单次安装)

若执行过 hstack setup-from-source --profile=dev,安装向导会询问是否代为安装 dev-client。

通过 USB 连接 iPhone,安装专用的 hstack dev-client 应用。

该命令会执行预构建(prebuild)(生成 ios/ 并运行 CocoaPods),随后安装 Debug 构建,中途不会启动 Metro:

hstack mobile-dev-client --install

如果需要确保 dev-client 基于特定栈的当前代码工作树进行构建(例如引入尚未合并到默认检出分支的上游变更),可运行:

hstack stack mobile-dev-client <stack> --install

可选操作:

hstack mobile-dev-client --install --device="Your iPhone"
hstack mobile-dev-client --install --clean

随后启动任意栈并启用移动端支持:

hstack tui stack dev <stack> --mobile
# or (without TUI):
hstack stack dev <stack> --mobile
# or:
hstack dev --mobile

注意事项:

  • 局域网连通要求:使用真机 iPhone 时,必须确保 Metro 可通过局域网访问。
    • 针对移动端,hstack 默认配置为 lan,并会输出二维码和深度链接。
    • 模拟器通常可直接使用 localhost(参见下文的 Kaiwu_STACK_MOBILE_HOST)。
  • 若 Expo 已在纯 Web 模式下运行:请加上 --mobile 重新执行 --restart。

单栈专属应用安装(相互隔离)

为指定栈安装隔离的应用(具备独立的 Bundle ID 和 Scheme,使用 Release 配置,不依赖 Metro):

hstack stack mobile:install <stack> --name="Kaiwu (<stack>)"
hstack stack mobile:install <stack> --name="Kaiwu PR 272" --device="Your iPhone"

选定的应用名称会持久化保存在该栈的环境变量中,后续重新安装无需重复输入。

重新生成 iOS 原生工程 / “prebuild”(关键步骤)

在以下情况下,需要重新生成 iOS 原生工程与 Pods:

  • 拉取的代码变更影响了原生依赖或 Expo 配置
  • apps/ui/ios/ 被误删
  • 升级依赖后遇到 CocoaPods 或 Deployment Target 不匹配的问题

运行:

hstack mobile --prebuild
# (optional) fully regenerate ios/:
hstack mobile --prebuild --clean

该命令当前执行的操作如下:

  • 运行 expo prebuild --no-install(以便在 CocoaPods 运行前完成补丁)
  • 为 ios/Podfile.properties.json 打补丁:
    • 将 ios.deploymentTarget 设为 16.0
    • 将 ios.buildReactNativeFromSource 设为 true
  • 修补生成的 Xcode 工程的 Deployment Target(在适用的情况下)
  • 运行 pod install

注意事项:

  • 通常无需手动执行该步骤,因为以下两个命令均已内置 --prebuild:
    • hstack mobile-dev-client --install
    • hstack stack mobile:install ⟦K23⟧
  • 历史别名:虽保留有隐藏别名 hstack mobile:prebuild,但建议优先使用 hstack mobile --prebuild。

手动调用 hstack mobile(高级用法)

如果希望直接针对内置的 Expo 应用开发(脱离 hstack dev --mobile),hstack mobile 支持以下命令:

# Start Metro (keeps running):
hstack mobile --host=lan

# Build + install on iOS (and exit). If you omit --device, it will try to auto-pick a connected iPhone over USB:
hstack mobile --prebuild --run-ios --device="Your iPhone"
hstack mobile --prebuild --run-ios --configuration=Release --no-metro

说明与排错指南

  • 扫码打开了错误的应用:

    • dev-client 二维码使用的是 Kaiwu_STACK_DEV_CLIENT_SCHEME(默认值:hstack-dev)。
    • 单栈专属安装采用专属于各自栈的 Scheme,因此不会拦截 dev-client 的扫码操作。
  • 列出已连接的设备(用于 --device=):

hstack mobile:devices
  • iPhone 真机代码签名异常:
    • hstack 会尝试取消生成文件 .pbxproj 中固定的签名配置字段,以便 Expo/Xcode 重新配置签名(从而避免因固定了 DEVELOPMENT_TEAM 或描述文件而导致自动签名失效的问题)。
    • 如需手动管理签名,可向 hstack mobile ... / hstack stack mobile ⟦K24⟧ ... 传入 --no-signing-fix。

将默认服务器 URL 固化到应用中(可选)

如果希望打包出的应用默认指向你的 hstack 服务器 URL,请在构建时设置:

Kaiwu_STACK_SERVER_URL="https://<your-machine>.<tailnet>.ts.net" hstack mobile-dev-client --install

注意:修改 Kaiwu_STACK_SERVER_URL 后,必须重新构建并安装目标应用。

提示:Kaiwu_STACK_SERVER_URL 应填入手机能够访问的规范/共享 URL。在自托管部署中,服务端对应的配置项为 Kaiwu_PUBLIC_SERVER_URL(两者取值通常一致)。

重要提示:

  • 针对非主栈,Kaiwu_STACK_SERVER_URL 只有在该栈自身的环境变量文件中设置时才会生效(安全考量:对非主栈忽略“全局”URL,以防误修改其他栈的指向)。

自定义应用标识(可选 / 高级用法)

hstack 预设了以下应用标识:

  • Dev-client:默认为 Kaiwu Dev,Bundle ID 为 dev.Kaiwu.stack.dev.⟦K25⟧
  • 单栈 Release 应用:默认为 Kaiwu (⟦K26⟧),Bundle ID 为 dev.Kaiwu.stack.stack.⟦K27⟧.⟦K28⟧

如果希望手动构建/安装(而非使用 mobile-dev-client / stack mobile:install),可以覆盖以下配置:

  • Bundle Identifier(推荐真机 iPhone 使用):
    • 若当前 Bundle ID 未归属你的 Apple 开发者团队或已被占用,则需要进行覆盖。
Kaiwu_STACK_IOS_BUNDLE_ID="com.yourname.hstack.dev" hstack mobile --prebuild --run-ios --no-metro
  • 应用名称(显示在主屏幕上的名称):
Kaiwu_STACK_IOS_APP_NAME="hstack" hstack mobile --prebuild --run-ios --no-metro

推荐环境变量配置

建议将以下内容加入主栈的环境变量文件(~/.Kaiwu/stacks/main/env)(或写入 ~/.Kaiwu-stack/env.local 作为全局覆盖项),无需在每条命令前重复添加前缀:

# How the phone reaches Metro:
# - lan: recommended for real devices
# - localhost: OK for simulators
Kaiwu_STACK_MOBILE_HOST="lan"

# (optional) default scheme used in the dev-client QR / deep link
# (must match your installed dev-client app):
Kaiwu_STACK_DEV_CLIENT_SCHEME="hstack-dev"

# Default public server URL for the stack (baked into the Expo app config):
Kaiwu_STACK_SERVER_URL="https://<your-machine>.<tailnet>.ts.net"

# Optional: home screen name:
Kaiwu_STACK_IOS_APP_NAME="Kaiwu"

基于 EAS 的单栈构建(生产级 / 类 App Store 环境)

本节详细说明如何为指定栈生成完全可用的云端 EAS Build 端到端工作流。该流程支持自定义 Bundle ID 与应用名称(例如:dev.Kaiwu.app / Kaiwu),并在未设置环境变量时保持上游默认值不变。

概述

若要为单栈特定应用标识生成可靠的 EAS 构建,通常需要:

  • 包含应用配置钩子(动态 app.config.js)的 Kaiwu 单体仓库(monorepo)工作树
  • 一个绑定到该工作树的栈(hstack stack wt ⟦K29⟧ -- use ...)
  • 用于描述应用标识(Bundle ID、应用名、Scheme 等)的栈环境变量
  • 在 Expo 上配置好 EAS 环境变量(确保云端构建机能读取到相同的值)
  • 首次构建时完成交互式凭据配置(iOS 签名),此后方可支持非交互式构建
  • 标识变更时:执行 prebuild,使 ios/ 与 android/ 原生工程同步更新为新的标识

1) 创建(或选择)栈并绑定工作树

以栈名称 kaiwu 为例。

从你的 Fork 分支创建单体仓库工作树(示例):

hstack wt new local/kaiwu-eas --from=origin --base=origin/dev --use

将 kaiwu 栈绑定到该工作树:

hstack stack wt kaiwu -- use local/kaiwu-eas

2) 在栈环境变量中设置应用标识(本地与构建期配置)

构建期间,apps/ui/app.config.js 会读取并评估这些变量:

hstack stack env kaiwu set \
  APP_ENV=production \
  EXPO_APP_NAME="Kaiwu" \
  EXPO_APP_BUNDLE_ID="com.wujilabs.kaiwu" \
  EXPO_APP_SCHEME="kaiwu" \
  EXPO_APP_SLUG="kaiwu" \
  EXPO_APP_OWNER="wuji-labs"

注意事项:

  • APP_ENV 用于控制内置的变体逻辑(development / preview / production)。
  • 未设置环境变量时,EXPO_APP_* 覆盖逻辑会完整保留上游默认值。

3) 更改标识时重新生成原生工程(“prebuild”)

修改 Bundle ID、Scheme 或配置插件后,建议执行一次干净的预构建,以确保原生工程与最新配置同步:

hstack stack mobile kaiwu --prebuild --platform=ios --clean --no-metro
# or:
hstack stack mobile kaiwu --prebuild --platform=all --clean --no-metro

4) 确保云端构建机能够读取环境变量(EAS 环境变量)

云端构建不会自动继承本地终端的环境变量。必须在 Expo(项目设置)中配置 EAS 环境变量,并确保构建 Profile 选中了对应的环境。

EAS 项目环境变量配置流程:

  1. 确保 apps/ui/eas.json 的构建 Profile 已设置 "environment": "production" / "preview" / "development"。
  2. 将相关 EXPO 配置环境变量同步到 EAS 的对应环境中(类型设为明文 Plain text 或敏感 Sensitive,确保 app.config.js 能够读取)。

推荐做法(使用栈作用域同步工具):

hstack stack eas kaiwu env:sync --environment production
# preview/development:
hstack stack eas kaiwu env:sync --environment preview
hstack stack eas kaiwu env:sync --environment development

# Safety knobs:
hstack stack eas kaiwu env:sync --environment production --dry-run
hstack stack eas kaiwu env:sync --environment production --hide-values

注意事项:

  • env:sync 会使用当前栈环境变量的值(例如 EXPO_APP_*、EXPO_EAS_PROJECT_ID、EXPO_UPDATES_URL、EXPO_UPDATES_CHANNEL、EXPO_APP_LINK_HOST)。
  • env:sync 不会同步 EXPO_PUBLIC_*(这些变量是在打包时内嵌的;请视情况使用 apps/ui/eas.json 或 EAS 环境变量界面进行配置)。

手动查看 EAS 配置(调试单个变量时依然实用):

hstack stack eas kaiwu env:list --environment production

提示:

  • 如果看到 “No environment variables with visibility Plain text and Sensitive found…”,说明 EAS 环境变量尚未添加(或被设置成了 secret)。

5) EAS 项目与账号状态检查

若遇到权限报错,请核实当前登录的 Expo 账号:

hstack stack eas kaiwu whoami
hstack stack eas kaiwu login

若该项目尚未在你的账号下初始化或关联:

hstack stack eas kaiwu project:init

6) 构建(iOS / Android)

首次配置 iOS 签名凭据通常需要采用交互模式:

hstack stack eas kaiwu ios --profile production --interactive

凭据配置完成后,即可运行非交互式构建:

hstack stack eas kaiwu ios --profile production --no-wait --non-interactive
hstack stack eas kaiwu android --profile production --no-wait --non-interactive

常见问题排查

  • eas.json is not valid / "build.base" must be of type object:
    • 你的 eas.json 使用了旧版 Schema;请将 build.base 更新为对象结构,并改用 "extends": "base"。
  • Credentials are not set up. Run this command again in interactive mode.:
    • 附带 --interactive 重新执行相同的构建,完成一次 iOS 签名配置即可。
  • 云端构建无法读取栈环境变量:
    • 请在项目设置中配置 EAS 环境变量,并确认构建 Profile 中包含 "environment": "production"。
© 乾元执中(南京)科技有限公司 · WUJI-Labs

On this page