跳转至正文
教程

在 Linux 上用 Capacitor 和 Capgo Build 构建 iOS App

在 Ubuntu、Fedora 或任意 Linux 机器上,把签名的 iOS 构建发布到 TestFlight:用 Capacitor 生成 ios/ 项目,用 OpenSSL 创建证书,再让 Capgo Build 无需 Mac 即可编译并提交。

在 Linux 上用 Capacitor 和 Capgo Build 构建 iOS App

Linux 是编写 Capacitor 应用的理想环境,且 Android 构建也能完美运行。但 iOS 是个例外:Xcode 和 Apple 的签名工具只能在 macOS 上运行。解决办法并不是在桌下塞一台 Mac mini,而是在本地生成 iOS 项目,然后在云端 macOS 上进行编译。

本指南是以下内容的 Linux 版本: 使用 Capacitor 和 Capgo Build 从 Windows 构建 iOS 应用。它涵盖了 Linux 环境下的差异点:OpenSSL 证书、Linux shell 以及通过 Linux runner 进行 CI。

分工模式

一个 Capacitor 应用包含两次构建:

  • Web 构建: 即你在 dist/中生成的框架输出。在 Linux 上完成。
  • Native Build: Xcode 打包、签名与上传。由 Capgo 构建 运行最新 macOS 和 Xcode 的 Apple Silicon 设备完成。

CLI 会上传准备好的 ios/ 项目。无需将代码托管至 Git,也不会泄露私有仓库凭据,因为依赖安装和 cap sync 构建均在上传前于本地完成。

前提条件

  • 支持本地构建(任何框架)的 Capacitor 应用。
  • Linux 上的 Node 20+ 或 Bun。
  • Apple Developer Program 会员资格。
  • OpenSSL(几乎所有发行版都默认安装)。
  • 一个 Capgo 账号,以及已注册到该账号的应用 bunx @capgo/cli@latest app add.

1) 在 Linux 上生成 iOS 项目

bun add @capacitor/core @capacitor/ios
bun add -d @capacitor/cli
bunx cap init
bun run build
bunx cap add ios

你会看到类似以下的内容 Skipping pod install because CocoaPods is not installed。这是正常的。该 ios/ 文件夹已存在,应当提交;它包含了你的 bundle ID、Info.plist、图标和原生配置。

2) 每次构建前同步 Web 资源

bun run build
bunx cap sync ios

cap sync 复制 dist/ 为 ios/App/App/public 并更新插件引用。Capgo 会编译其中的 ios/,因此未同步的项目会发布旧版 UI。

3) 无需 Mac 即可创建签名材料

你需要三样东西:Apple Distribution 证书、 .p12App Store provisioning profile 以及 App Store Connect API key。这些都不需要使用 Keychain Access。

使用 OpenSSL 生成 Distribution certificate

openssl genrsa -out ios_distribution.key 2048
openssl req -new -key ios_distribution.key -out ios_distribution.csr \
  -subj "/emailAddress=you@example.com/CN=Your Name/C=US"

上传 ios_distribution.csr 在 Certificates, Identifiers & Profiles 中,选择 Apple Distribution 并下载 distribution.cer。进行转换并打包:

openssl x509 -in distribution.cer -inform DER -out distribution.pem -outform PEM
openssl pkcs12 -export -inkey ios_distribution.key -in distribution.pem \
  -out ios_distribution.p12 -legacy

本指南中介绍的 -legacy flag 在 OpenSSL 3 中非常重要。如果不使用它,Apple 的工具会拒绝 .p12 即使密码正确也会提示密码无效错误。如果你不想动 OpenSSL,那么 iOS 证书生成器 在浏览器中也能实现同样的操作。

Provisioning profile 和 API 密钥

在 Apple Developer 门户中,为你的 bundle ID 创建一个使用新证书的 App Store profile,并下载 .mobileprovision。在 App Store Connect 中,创建一个具有 App Manager 角色的 API 密钥并下载 .p8;请记录下 Key ID 和 Issuer ID。 iOS Build 指南 会显示每个屏幕。

想在 Linux 上检查 profile 吗? openssl smime -inform der -verify -noverify -in profile.mobileprovision 会打印出嵌入的 plist。

4) 将凭据保存在 Capgo 中

bunx @capgo/cli@latest login
bunx @capgo/cli@latest build credentials save \
  --platform ios \
  --apple-team-id "TEAMID" \
  --apple-key ./AuthKey_KEYID.p8 \
  --apple-key-id "KEYID" \
  --apple-issuer-id "issuer-uuid" \
  --certificate ./ios_distribution.p12 \
  --ios-provisioning-profile ./App_Store.mobileprovision

或者运行 bunx @capgo/cli@latest build init --platform ios 来使用引导模式。在 Linux 上,App Store Connect 密钥步骤需要手动完成;其余步骤都会有提示。

如果 Apple 因身份验证错误拒绝该密钥,请同步系统时间。JWT 使用本地时间签名,Apple 会拒绝偏差过大的 token:

timedatectl status
sudo timedatectl set-ntp true

5) 发起构建

bun run build
bunx cap sync ios
bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release

准备好的 ios/ 项目会上传,Capgo 会运行 pod install,用 Xcode 归档,用你的证书签名,并将日志流式输出到终端。配置好 API 密钥后,构建完成后会提交到 TestFlight。在 iPhone 上安装 TestFlight 应用即可运行。

失败的构建可以通过添加以下功能自动诊断: --ai-analytics; AI 构建诊断 读取 Xcode 日志并说明修复方法。

6) 为没有 TestFlight 的测试人员提供 Ad hoc 构建

对于通过 UDID 注册的 QA 设备,请使用 Ad Hoc profile,并将 IPA 作为产物保留:

bunx @capgo/cli@latest build request com.example.app \
  --platform ios \
  --ios-distribution ad_hoc \
  --output-upload

CLI 会输出一个限时下载链接。添加 --output-record build.json 以保存链接,以及给测试人员的 QR code。

7) 在 Linux CI runner 上实现自动化

相同的命令可在任何 Linux CI 上运行。下面是一个 GitHub Actions 示例:

name: iOS build
on:
  workflow_dispatch:
jobs:
  ios:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: oven-sh/setup-bun@v2
      - run: bun install
      - run: bun run build
      - run: bunx cap sync ios
      - run: bunx @capgo/cli@latest build request com.example.app --platform ios --build-mode release
        env:
          CAPGO_TOKEN: ${{ secrets.CAPGO_TOKEN }}

第 4 步保存的凭据存储在 Capgo 中,因此 runner 只需要 token。或者,导出 CI .env 配合 bunx @capgo/cli@latest build credentials manage 并将这些值作为 secrets 传入;参见 凭据管理.

8) 无需原生构建的日常迭代

TestFlight 构建就绪后,大部分改动都是 Web 改动。使用 Capgo Live Updates:

bun run build
bunx @capgo/cli@latest bundle upload --channel production

仅在 build request 用于添加插件、更改权限、修改图标以及 Capacitor 升级。

Linux 环境下的坑

  • 忘记 cap sync ios: IPA 显示的是旧 UI。每次请求前请先同步。
  • ios/ 中的 .gitignore: CLI 从本地磁盘上传,所以构建能通过,但你的队友和 CI 会缺少原生项目。请提交它。
  • .p12 密码被拒绝: 请使用以下方式重新生成 -legacy.
  • Apple 身份验证失败: 时钟偏移。请启用 NTP。
  • 添加了插件,却忘了进行 Native Build: 添加 Capacitor 插件会改变原生二进制文件。在发布调用该插件的 Web 更改之前,请运行新的云端 build 并提交至应用商店。

总结

Linux 无法运行 Xcode,但其实并不需要。通过 ios/ 使用 Capacitor,配合 OpenSSL 生成 build 证书,并让 Capgo Build 进行编译、签名并发送至 TestFlight。配合针对 Web 层的 Live Updates,仅使用 Linux 的团队也能像发布 Android 应用一样常规地发布 iOS 应用。了解完整的环境配置,请阅读 在 Linux 上开发 Capacitor.

为 Capacitor 应用提供 Live Updates

当 Web 层出现线上 Bug 时,通过 Capgo 发布修复,而不用等 App Store 审核好几天。用户会在后台收到更新,原生变更则仍走正常审核流程。

博客最新动态

Capgo 为你提供打造真正专业的移动应用所需的最有价值的洞察。