移动端 (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)。
- 针对移动端,hstack 默认配置为
- 若 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 --installhstack 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 的扫码操作。
- dev-client 二维码使用的是
-
列出已连接的设备(用于
--device=):
hstack mobile:devices- iPhone 真机代码签名异常:
- hstack 会尝试取消生成文件
.pbxproj中固定的签名配置字段,以便 Expo/Xcode 重新配置签名(从而避免因固定了DEVELOPMENT_TEAM或描述文件而导致自动签名失效的问题)。 - 如需手动管理签名,可向
hstack mobile .../hstack stack mobile ⟦K24⟧ ...传入--no-signing-fix。
- hstack 会尝试取消生成文件
将默认服务器 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-eas2) 在栈环境变量中设置应用标识(本地与构建期配置)
构建期间,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-metro4) 确保云端构建机能够读取环境变量(EAS 环境变量)
云端构建不会自动继承本地终端的环境变量。必须在 Expo(项目设置)中配置 EAS 环境变量,并确保构建 Profile 选中了对应的环境。
EAS 项目环境变量配置流程:
- 确保
apps/ui/eas.json的构建 Profile 已设置"environment": "production"/"preview"/"development"。 - 将相关 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:init6) 构建(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"。
- 请在项目设置中配置 EAS 环境变量,并确认构建 Profile 中包含