怎么给 Cordova / Capacitor / Ionic 项目签名打包成 iOS 应用并上架 App Store?

0 阅读5分钟

Cordova、Capacitor、Ionic 这一系说白了都是把网页装进原生壳里,壳那部分就是个标准 Xcode 工程。所以编译签名这一步跑不掉 macOS——本地的 Mac,或者 Ionic Appflow、Codemagic 这类云构建服务的 macOS 机器。

但不管你走哪条路,第一件事都是准备 .p12 证书和 .mobileprovision 描述文件——云构建服务的表单里第一项要你填的就是这两个。我当初就卡在这儿:教程全都让你在 Mac 上开「钥匙串访问」,而我手边只有 Windows。后来用开心上架(AppUploader)在 Windows 上直接签出来,这一步就不是障碍了。

先说结论:哪一步真绕不开 Mac

环节我实际怎么做的
注册 Bundle ID、签发证书、生成描述文件Windows 上做完
编译签名成 IPA要 macOS——本地 Mac 或云构建服务的 macOS 机器
提交 App StoreWindows 上传
装到 iPhone 测试扫码注册 UDID,再扫码装

说清楚一点:我用的工具本身是跨平台的,网页版在 macOS、Windows、Linux 的浏览器里都能开,桌面客户端也有 macOS 版。表里"不需要 Mac"指的是这一步不再被 Xcode、钥匙串访问、Transporter 卡住,不是说它只服务 Windows 用户。

第一步:确认 App ID

  • Cordova 看 config.xml 根节点的 id 属性,比如 <widget id="com.yourcompany.appname" ...>
  • Capacitor 看 capacitor.config.ts / capacitor.config.json 里的 appId

Cordova 这边有个坑:id 改完之后最好 cordova platform rm ios && cordova platform add ios 重新生成一次原生工程,不然旧的 Info.plist 里还留着老值,签名会失败。

第二步:在 Windows 上签出两个文件

注册 Bundle ID:开心上架的「Bundle ID」页面点「新建 Bundle ID」,Identifier 填第一步那个字符串。创建后改不了。用到推送、Associated Domains、App Groups 这些能力的,在这个 Bundle ID 的「权限」页面勾上再保存——插件要求的权限如果没在这里开,装到手机上功能会静默失效,排查起来很浪费时间。

签发证书:「证书」页面点「新建证书」,上架选发布签名证书,真机调试选开发签名证书。绑定 Bundle ID,填名称邮箱,设一个 .p12 保护密码,服务器不保存这个密码,自己记牢。顺手勾上「使用开心上架服务同步证书」,换机器时能重新下载同一张。

生成描述文件:「描述文件」页面点「新建描述文件」,上架选 App Store 类型,内测选 Ad Hoc 并勾上测试设备,关联上面的 Bundle ID 和证书,提交后下载 .mobileprovision生成描述文件

CSR 和私钥都在本机生成,不经过 Mac 的钥匙串。

第三步:把签名配置写进构建流程

Cordova 用 build.json。工程根目录放一个:

{
  "ios": {
    "release": {
      "codeSignIdentity": "Apple Distribution",
      "developmentTeam": "你的TeamID",
      "provisioningProfile": "描述文件的UUID",
      "packageType": "app-store"
    }
  }
}

注意 provisioningProfile 要填的是描述文件的 UUID,不是名称也不是文件路径。我第一次填了文件名,构建一直报找不到 profile。

UUID 从哪看?在开心上架的「文件&提交」页面直接把 .mobileprovision 打开,详情里 UUID、绑定的 App ID、关联证书、有效期都列出来了,比在 Mac 上敲 security cms 解一遍方便。

然后在 macOS 上跑:

cordova build ios --release --device --buildConfig=build.json

Capacitor / Ionic 走 Xcode 工程。Capacitor 生成的就是个正常的 Xcode 工程:

npx cap sync ios
npx cap open ios     # 在 macOS 上打开 Xcode

在 Signing & Capabilities 里关掉 Automatically manage signing,手动选证书和描述文件,然后 Product → Archive。有 CocoaPods 依赖的话记得开 .xcworkspace 而不是 .xcodeproj

CI 上则是把两个文件用 base64 存进加密变量,构建时解码、security import 进临时钥匙串、描述文件拷到 ~/Library/MobileDevice/Provisioning Profiles/,再用 xcodebuild archivexcodebuild -exportArchive 出包。

云构建服务。Ionic Appflow、Codemagic 这些的 iOS 构建配置里,会让你上传「Signing Certificate(.p12 + 密码)」和「Provisioning Profile」,填的就是第二步那两个文件。传上去之后云端的 macOS 机器帮你编译签名,本地始终 Windows。

第四步:把 IPA 传上去

我一般先在开心上架的「文件&提交」页面把包打开确认签名信息,再点「提交 App Store」。

命令行:

appuploader-cli upload -f App.ipa -u dev@example.com -p abcd-efgh-ijkl-mnop

-p 是 Apple 生成的 App 专用密码(xxxx-xxxx-xxxx-xxxx),不是登录密码。团队用 API 密钥更合适:

appuploader-cli upload -f App.ipa --api-key <KeyID> --api-issuer <IssuerID> --private-key Auth_Key.p8

密钥方式只收 .ipa,且 App 要先在 App Store Connect 里建好。这条命令不依赖 macOS。

上传前还有件事值得检查:Info.plist 里的隐私用途说明。Cordova/Capacitor 的插件会顺带引入相机、相册、定位这些权限,NSCameraUsageDescription 这类字段缺了的话,上传或者审核阶段会被打回来。

第五步:发内测包

「设备」页面点「注册设备」,二维码发出去让人扫上报 UDID(一年 100 台,免费账号 3 台)。回描述文件那边点「重建」生成一份包含这些设备的 Ad Hoc 描述文件。

build.jsonpackageType 换成 ad-hocprovisioningProfile 换成新 UUID,重新构建,然后在「文件&提交」页面生成二维码让人扫码装。

这一系技术的编译环节确实要 macOS,但那台机器你可以只当编译节点用——证书要不要续、描述文件要不要重建、包传没传上去,这些日常操作全能在 Windows 上处理。

我用的是开心上架网页版,打开就能用。卡在云构建服务那个"上传签名文件"表单上的话,可以照着上面走一遍。