前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

Ionic 项目 iOS 打包真机调试与上架 App Store 全流程

首页2019-10-07 08:10:24Front-End
IonicAngulariOSCordova打包发布

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 要去下载平台模板和一堆依赖,网络不通就会卡在这里报错。

执行 ionic cordova platform add ios 时因网络问题下载失败的报错信息

  • 使用软件中的提供的翻墙工具重试,如果不行继续看第二步骤
  • 手机开启热点,让电脑连接手机用手机的网络下载

这两条是当年的应急办法。更工程化的解法是给 npm 配国内镜像,再给终端配好代理环境变量(export https_proxy=...),因为 Cordova 底下有一部分下载走的是它自己的进程,不读 npm 的配置,只认环境变量。这个我排查了一下午才想明白,光在 .npmrc 里配镜像是不够的。

找到对应目录下面的文件双击用 Xcode 打开

平台加好之后,platforms/ios 目录下会生成一整套 iOS 原生工程,找到那个工程文件双击,Xcode 就会接管。

在 platforms/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 顶部工具栏的设备下拉里选一个模拟器,点左边的运行按钮。

在 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 连接 iPhone 后进入设备摘要页 点击序列号处切换显示为 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 注册进去。

在苹果开发者中心的 Devices 页面注册设备 UDID

这里有个坑要注意,而且是这一整篇里最容易白费时间的一个:新注册的设备不会让已经打好的旧包突然能装。设备列表是被写进描述文件、描述文件又被打进 ipa 里的,所以加完设备之后必须回后台把描述文件重新生成一遍,然后重新 Archive 重新导出,测试同学下新链接才行。这条我踩过,加完设备让人重装了三次同一个包。

另外注册进去的设备是要占额度的,删除还只能在会员年度续费时操作,所以别拿它当草稿本用,随手把同事的旧手机全塞进去,年底会不够用。

# 3.3 用 Xcode 自动管理证书文件

手动创建证书文件参考下面地址:

https://jingyan.baidu.com/article/d3b74d640735c71f77e609f0.html

现在用 xcode 开发项目我们可以自动适配我们的证书,选择自动化配置证书意味着你不会 在证书设置和编译的时候浪费更多的时间,并且你可以更好的设置适合你的 Xcode

fe
  • 一、先说清楚这套栈现在的状态
  • 二、先在模拟器里跑起来
  • 三、真机调试
    • 3.1 真机调试之前的准备工作
    • 3.2 开发者中心配置调试设备的 UDID
    • 3.3 用 Xcode 自动管理证书文件
    • 3.4 真机调试
  • 四、创建测试包 ipa
  • 五、发布到 App Store
    • 5.1 登录 iTunes Connect 创建应用
    • 5.2 配置发布证书并打正式包
    • 5.3 用 Application Loader 上传构建版本
    • 5.4 直接在 Xcode 中上传应用
  • 六、打包上传前,在 info.plist 添加权限
  • 总结
  • 参考

← Ionic 调用原生相机与 Cordova 插件命令实战Vue核心梳理 组件通信 生命周期 Vuex 与路由原理 →