Ionic 项目写完了,浏览器里跑得挺好,接下来才是真正的关卡:怎么把它变成一个能装到 iPhone 上、最后躺进 App Store 的东西。这条路上你会在终端、Xcode、苹果开发者后台、App Store Connect 四个地方来回跳,任何一步没对齐,报出来的错都长得像天书。
这篇是我当年把这条路整个走通一遍留下的记录,六十多张截图基本覆盖了每一次点击。每张图前面我补了「这一步在做什么」,后面补了「做完应该看到什么、这里的坑在哪」,照着走应该不至于卡死。
在本篇文章中,我们将从浅入深,和大家一起学习以下知识:
Ionic项目怎么加 iOS 平台,为什么每次改完代码都得跑build加prepare- 模拟器跑起来的完整路径,以及双击工程文件打不开时的权限处理
- 设备
UDID从哪拿、配到哪去,iTunes没了之后换什么方式取 - 用
Xcode自动管理证书,比手动折腾 CSR 省多少事 Archive打测试包ipa的八步操作,以及 code sign 类报错怎么读- 在
App Store Connect建应用、传构建版本的两条路径(Application Loader和Xcode) - 上架前
Info.plist里那十几个权限描述键,漏一个就会被打回 - 这套技术栈今天的状态,以及这篇内容哪些还有效、哪些已经变了
# 一、先说清楚这套栈现在的状态
这篇写于 2019 年,用的是 Ionic 3 加 Cordova。Apache Cordova 现在已经不再活跃维护,项目退役进了 Apache Attic 归档,具体以 https://attic.apache.org/ 上的公告为准。Ionic 官方推的原生方案换成了 Capacitor,新项目建议直接走那条路。
但这篇里真正占篇幅的东西,其实跟 Cordova 关系不大。苹果那套签名、打包、上架的流程,是横在所有 iOS 应用面前的同一道关,用 Cordova、用 Capacitor、用 React Native、写纯原生,走的都是同一批界面。所以下面第三节往后的内容,换个技术栈照样能用,只有第二节那几条 ionic cordova 命令是这套栈特有的。
顺带说一下这篇和 RN 构建 iOS 包发布到 AppStore 全流程 的分工。那篇是从 React Native 项目出发的,讲得更细的是签名体系本身:App ID、证书、描述文件、设备这四样东西各自管什么、怎么串起来、描述文件为什么一变就得重新打包。这篇则是操作流水线,从终端命令一直到点提交审核,胜在步骤密度。两篇配着看正好,概念不清就翻那篇,忘了下一步点哪就翻这篇。
界面方面有几处这些年确实变了,我在对应位置都会标出来,最主要的三处是:iTunes Connect 改名成了 App Store Connect;Application Loader 被 Xcode 移除,替代品是独立的 Transporter App;iTunes 在新版 macOS 上被拆掉了,取 UDID 得换别的路子。
# 二、先在模拟器里跑起来
上真机之前,先确保项目能在模拟器里出画面。这一步走通,说明构建链路是好的,后面出问题就可以专心排查签名。
安装 Ionic 与 Cordova
sudo cnpm install -g cordova ionic
这条是原文的命令,我保留。但现在别照抄了,两个地方要改:cnpm 装全局 CLI 容易出怪问题(它用的是软链接式安装),换回 npm 加镜像更稳;sudo 装全局包会让 node_modules 里一堆文件属主变成 root,后面装插件时权限问题就是这么来的,更好的做法是用 nvm 管理 Node,全局目录在用户空间里,根本不需要 sudo。
Ionic 创建浏览器运行的项目
- 创建项目:
sudo ionic start myApp tabs - cd 到刚才创建的项目
sudo ionic serve浏览器运行项目
tabs 是模板名,起手用它比 blank 省事,因为底部导航、页面结构、路由都给你搭好了,直接照着改。
Ionic 借助 cordova 创建 ios 手机上可以安装的应用
- 创建项目:
sudo ionic start myApp tabs - cd 到刚才创建的项目
sudo ionic cordova platform add ios把 ios 环境添加到我们的项目sudo yarn install- 修改代码后运行
sudo ionic build --prod(打包) 以及sudo ionic cordova prepare(这个是拷贝www目录资源到ios工程下)。必须运行,否则调试会卡死
最后那条是这一节最关键的一句,值得单独拎出来说。
ionic build 干的事是把 src 下的 TypeScript 和模板编译成静态资源,产物落在项目根目录的 www。而 Xcode 打开的那个原生工程读的是 platforms/ios/www,两者是两份文件。cordova prepare 就是把前者拷到后者,顺带把插件配置同步进原生工程。
漏了这两步的表现特别迷惑:代码明明改了,模拟器里跑的还是老版本,你会开始怀疑是缓存、是没重新编译、是 Xcode 抽风。其实只是资源没拷过去。建议直接把这两条命令串成一个 npm 脚本,别指望每次都记得手动跑。
可能遇到的错误以及解决方案
加 iOS 平台的时候,Cordova 要去下载平台模板和一堆依赖,网络不通就会卡在这里报错。

- 使用软件中的提供的翻墙工具重试,如果不行继续看第二步骤
- 手机开启热点,让电脑连接手机用手机的网络下载
这两条是当年的应急办法。更工程化的解法是给 npm 配国内镜像,再给终端配好代理环境变量(export https_proxy=...),因为 Cordova 底下有一部分下载走的是它自己的进程,不读 npm 的配置,只认环境变量。这个我排查了一下午才想明白,光在 .npmrc 里配镜像是不够的。
找到对应目录下面的文件双击用 Xcode 打开
平台加好之后,platforms/ios 目录下会生成一整套 iOS 原生工程,找到那个工程文件双击,Xcode 就会接管。

注意:xcode 用最新的版本
这句要补一句背景。Xcode 版本和 iOS SDK 是绑定的,太老的 Xcode 编不出支持新系统的包,苹果对上架包的最低 Xcode 版本也有硬性要求,而且这个要求会随时间往上抬。所以「用最新版本」这个建议是对的。但反过来也有个坑:Cordova 生成的原生工程用的是老模板,遇到太新的 Xcode 有时候会因为新的构建规则报错,这种情况要么升 cordova-ios 平台版本,要么临时降 Xcode。
顺便提一句,如果你的项目装过带原生依赖的插件,Cordova 会用 CocoaPods 管理它们,这时候要打开的是 .xcworkspace 而不是 .xcodeproj,开错的表现是编译时一堆找不到头文件的错。
如果双击遇到权限问题如下

可以用命令修改权限,cd 到要修改权限的目录执行下面命令
sudo chmod -R 777 *
这个报错的根源就是前面那些 sudo。用 sudo 跑 ionic cordova platform add ios 生成出来的目录属主是 root,你当前用户没有写权限,Xcode 自然打不开。
chmod -R 777 能解决问题,但它是把所有人的读写执行权限全开了,属于大锤砸核桃。更干净的做法是把属主改回自己:
sudo chown -R $(whoami) ./platforms ./plugins
改完之后往后就别再用 sudo 跑 ionic 命令了,不然过两天又是同样的问题。
在 xcode 中选择对应模拟器运行
工程打开之后,在 Xcode 顶部工具栏的设备下拉里选一个模拟器,点左边的运行按钮。

注意:调整模拟器大小只需要拉动模拟器边缘即可
第一次编译会比较慢,之后就快了。模拟器里能看到你的页面,说明「代码 → 构建 → 拷贝 → 原生工程 → 跑起来」这条链路整个通了。
这里有个模拟器的局限要提前知道:相机、蓝牙、推送、定位这些原生能力在模拟器上要么不可用,要么是假数据。所以调 UI 用模拟器,调原生插件必须上真机,这也是下一节要做的事。
# 三、真机调试
# 3.1 真机调试之前的准备工作
- 你得有苹果开发者账号个人($99)、公司($99)、企业($299)账号均可
- 能上网的苹果电脑 macos(苹果虚拟机也可以)、Xcode、iOS 设备(iPhone、ipad 均 可)
价格这块我按当年记的原样保留,具体金额和账号类型以苹果官网当前公示为准,这些年调整过。
补一条当时没写的:如果只是想把 App 装到自己手边这台设备上调试,其实不需要付费账号。免费的 Apple ID 也能在 Xcode 里做真机调试,代价是证书有效期只有七天,到期得重新装一次,而且能装的 App 数量有限制。但只要你需要发给别人测试、需要上架,付费账号就是绕不过去的。
# 3.2 开发者中心配置调试设备的 UDID
先说个术语上的事。原文这里写的是 uuid,其实苹果那边叫 UDID(Unique Device Identifier,设备唯一标识),跟编程里常说的 UUID 不是一回事,别搜错关键词。下文我统一写成 UDID。
1. 获取 iPhone 手机的 UDID,手机连接电脑,打开 iTunes 软件,点击序列号字母处
这是当年最方便的办法:iTunes 连上设备之后,摘要页会显示序列号,在序列号那行文字上点一下,它会切换成 UDID,右键可以复制。

这条路现在走不通了,因为 iTunes 在新版 macOS 上被拆掉了。替代方式有三条,按方便程度排:
一是用 Finder,设备连上电脑之后会出现在 Finder 左侧边栏,点进去在设备信息那一行反复点击,同样会在序列号、UDID、IMEI 之间轮换。
二是用 Xcode,菜单走 Window → Devices and Simulators,选中设备,右侧的 Identifier 就是 UDID,这条最稳。
三是设备不在手边时,让对方用手机 Safari 打开分发平台的 UDID 获取页(比如蒲公英的工具页),按提示装一个描述文件,页面会把 UDID 显示出来让他复制发给你。
2. 配置 iPhone 手机的 UDID,打开平台开发者中心进行配置
拿到 UDID 之后,登录 https://developer.apple.com/account,进 Certificates, Identifiers & Profiles,在左侧 Devices 菜单里点加号,填设备名和 UDID 注册进去。

这里有个坑要注意,而且是这一整篇里最容易白费时间的一个:新注册的设备不会让已经打好的旧包突然能装。设备列表是被写进描述文件、描述文件又被打进 ipa 里的,所以加完设备之后必须回后台把描述文件重新生成一遍,然后重新 Archive 重新导出,测试同学下新链接才行。这条我踩过,加完设备让人重装了三次同一个包。
另外注册进去的设备是要占额度的,删除还只能在会员年度续费时操作,所以别拿它当草稿本用,随手把同事的旧手机全塞进去,年底会不够用。
# 3.3 用 Xcode 自动管理证书文件
手动创建证书文件参考下面地址:
https://jingyan.baidu.com/article/d3b74d640735c71f77e609f0.html
现在用 xcode 开发项目我们可以自动适配我们的证书,选择自动化配置证书意味着你不会 在证书设置和编译的时候浪费更多的时间,并且你可以更好的设置适合你的 Xcode