摘要:一个 iOS 应用最终能在用户的设备上使用,是经过了开发 -> 打包 -> 发布 -> 下载安装过程的。为了更易于理解,以及避免从一开始就陷入细节,本文将逆序讲述整个过程。

一、背景

在 iOS 开发中,大概每个新手都被各种配置、证书、打包和发布等事情折腾过,我亦如此。

教程一搜一大堆,照着教程 1234 也能做下来。但是在这个过程中,我会产生很多问号:

  • 为什么程序能在模拟器上运行,却无法在真机上运行?

  • 为什么不是每个人都能在本地打包?具备什么条件才能打包?

  • 为什么需要证书,描述文件?

  • 生成证书的原理是怎样的?

  • … …

很多事情是知其然而不知其所以然。

为了解决心中的疑惑,我借着项目的机会,研究了一番整个打包发布的流程,以及流程中每一步操作的背后都发生了什么。

之后便总结成了这篇文章,分享给大家,希望能使新手 iOS 开发同学对 iOS 的打包、发布和证书体系有更直观的了解。

一个 iOS 应用最终能在用户的设备上使用,是经过了 开发 -> 打包 -> 发布 -> 下载安装 的过程的。

为了更易于理解,以及避免从一开始就陷入细节,本文将逆序讲述整个过程。

二、iOS 应用的安装方式

作为一个 iOS 用户,我能通过哪些途径安装 app?

  1. App Store

    App Store 是 Apple 官方的 App 发布 平台。在 App Store 中搜索并安装 App,也是作为一个普通用户最常用的安装方式。

  2. TestFlight

    TestFlight 是 Apple 官方的 App 测试 平台。在上架到 App Store 之前,可以通过 TestFlight 邀请一部分用户参与测试,类似于网络游戏的公测。

  3. App Center, FIR…

    除了官方的 Apple Store 之外,市面上还存在着 App Center, FIR 等非 Apple 官方的 App 管理平台 。在开发过程中,我们通常会将各个环境的 App 上传到这些非官方的平台中,用于日常测试;另外,我们也会将其作为企业级应用的最终发布平台。

  4. 通过 Xcode 安装到 真机

  5. 通过 Xcode 安装到 模拟器

    在开发过程中,DEV 们作为特殊的 iOS 用户,也会通过 IDE 直接在真机或模拟器上进行开发和测试。这里把真机和模拟器分开,是因为它们确有不同。关于不同之处,我们将会在后文中谈到。

上面列出的,是用户,以及 DEV、QA 同学最常用的 5 种安装方式。那么这篇文章是要讲打包和发布,为什么我们要了解这些安装方式呢?

是因为不同的安装方式本身,背后就对应着不同类型的 发布 方式。

或者更严谨的说, 不同类型的发布方式,就决定了用这种发布方式打出来的 app,最终能通过哪种安装方式安装到机器上。

三、iOS 应用的发布方式

作为打包的那个人,我能通过选择发布方式,来决定我的应用能让哪些用户、通过何种安装方式下载安装

虽然我们有着以上不同的安装方式,但其实本质上都是从某个平台上,下载一个软件包到本地并安装(Xcode 除外)。

不同的平台做的也是同样的事情,即提供一个存放软件包的仓库,可供用户下载软件包。

发布,就是把软件包上传到发布平台。这步就无需赘述了。

那么我们再往前一步:打包

简单来说,所谓打包,就是将源码转换成 iOS 系统的软件包 -ipa 文件iPhone application archive

对于一个 iOS 应用,它的打包过程包括:

  1. 选择发布方式

  2. 选择证书和描述文件

  3. 编译 & 签名

  4. 导出 ipa 文件

本节我们关注第一步:选择一个发布方式。

Apple 提供了 4 种 发布方式:

iOS打包发布那些事儿

图 1 iOS 应用的发布方式
  1. App Store Connect - 上架 App Store 以及 TestFlight 的 app,用于生产环境发布

  2. Ad Hoc - 部分机器可安装的 app,用于非生产环境的测试

  3. Enterprise - 企业级应用发布

  4. Development - 与 Ad Hoc 类似,只有后续步骤所需要的证书和描述文件不同

结合上文,安装方式和发布方式之间的关系可以表示成:

iOS打包发布那些事儿

图 2 安装方式和发布方式之间的关系

我们再对比它们之间的主要区别:

iOS打包发布那些事儿

图 3 安装方式和发布方式之间的区别

从上图中我们能得出一些结论:

  • 能从 App Store 和 TestFlight 上安装使用的,一定是 App Store Connect 的发布方式。

  • 只有 App Store 中 app 和企业级应用没有安装数量上的限制。

  • 只要向真机上安装 app,无论选择哪种安装方式或发布方式,都需要证书,签名,描述文件。

这里我自己的一些额外猜想是,Apple 通过发布方式上的限制,确保真正 public 的应用只能通过 Apple 审核 ,App Store 下载安装。

但大家可能会发现,企业级应用也没有任何安装数量上的限制,甚至不需要审核。那是否可以把企业级应用 public 的发布呢?

答案是否定的。

首先,企业级应用需要 Apple 企业账号,Apple 对于企业级账号的发放是非常严格的。

其次,Apple 规定企业级应用的下载途径不可公开,若发现公开则会有封号,应用失效的后果。

因此,虽然从能力上看企业级应用能被安装在任意一台机器上,但是从途径上 Apple 限制了可能性。

至于 只要向真机上安装 app,都需要证书,签名,描述文件 ,我猜测这是对每一台设备负责吧。

现在我们讲完了打包的第一步发布方式,下一步就是选择证书和描述文件。

我们已经知道,只要向真机上安装 app,哪怕是 Xcode 直接运行,就都需要证书,签名,描述文件。

那么这些资源从哪来、怎么来,就是我们接下来的话题。

四、Apple Developer Account 和 Member Center

作为负责打包发布的人,我要如何、在哪管理开发和发布所需要的资源?

证书、描述文件等资源被维护在Member Center中。它是开发者的资源管理中心,可以全生命周期管理:

  • 证书,签名,描述文件等资源

  • TestFlight、Apple Store 上的应用

  • … …

登陆 Member Center 需要开发者账号Apple Developer Account

开发者账号有不同的类型。不同类型的开发者账号对应的 Member Center 拥有不同的能力。

1. 开发者账号的种类

iOS打包发布那些事儿

图 4 开发者账号的种类

从大类上,开发者账号分为三种:个人、组织和教育机构。教育机构这个类别我并没有接触过,也就不在这里深入。

在 4 个小类中,公司和个人类型的账号只有能否有团队成员这一个区别。因此实际上很多开发者会把个人类型的账号转为公司类型,便于团队协作。

也正是因为大多数应用都需要不止一个 DEV 来开发,所以比较常用的开发者账号类型就是支持development team的公司和企业级应用。

对于公司和企业级应用,二者之间除了账号的年费不一样之外,最重要的区别在于, 它能否将应用上架 App Store

那么为什么企业级账号无法将应用上架 App Store 呢?

这里大概解释一下:

从前文我们已经知道,想要上架 App Store,就必须选择App Store Connect的发布方式。

选了某种发布方式之后,后续步骤所需要的证书,描述文件等的类型也是不一样的。

在 Member Center 中,企业级账号只能生成发布企业应用所需的证书,无法生成 App Store Connect 的发布方式所需的证书,当然也就没有上架 App Store 的能力。

同样,公司账号也无法生成企业级证书,无法发布企业级应用。

2. Member Center 的用途之:管理 ID、设备、证书、描述文件

全生命周期管理 ID、设备、证书、描述文件,是 Member Cente 最重要的功能之一。

下面,我们分别看看它们的概念、用途和生成方式。

(1)ID - 唯一标识符,根据用途分为 App ID、Music ID、Merchant IDs 等

目前我们只考虑最简单的情况,就只介绍 iOS 应用必须的,用于标识一个或一组应用的 App ID。

下图即用公司类型的开发者账号注册一个 App ID 的过程:

iOS打包发布那些事儿

图 5 注册一个 App ID

从图中我们可以的看出:

  • App ID 需要指定应用平台

  • App ID 与 Team ID 绑定在一起。即,Apple 知道一个应用的 ID 是注册在哪个开发者账号下的,也只允许这个账号内的成员在真机上调试或打包。

  • App ID 指定了应用的capabilities,如:获取 WI-FI 信息、使用钱包、健康、SIRI…

(2)设备 - 能安装该开发者账号下的应用的设备

设备的概念就更简单了。每个苹果设备都有一个唯一标识符 UDID - Unique Device Identifier

将某个设备注册到开发者账号下,就是在注册时将该设备的 UDID 填入。同一台设备可以被注册到多个开发者账号下。

可以理解为开发者账号通过 UDID 列表,形成自己的设备资源池。

(3)证书 - 由 Apple 证书认证中心颁发的,用于确保应用内容可靠性和完整性的凭证

证书分为两种:

  1. 开发证书,用于日常开发 ;

  2. 发布证书,用于应用发布。

生成一个证书的步骤也很简单:

只需要在借助 keychain 在本地生成一个CSR 文件,然后通过开发者账号上传,成功后就会存在于证书资源池中,在失效前可随时使用下载(这里我们只需要了解生成证书的步骤,至于这个过程中都发生了什么,以及证书如何能确保应用的可靠性,我们后面会详述)。

iOS打包发布那些事儿

iOS打包发布那些事儿

图 6 生成一个证书

(4)描述文件 - 一个 ID,设备,证书的集合

你可能已经发现了,前面的 ID,设备和证书的都是各自独立的,我们看不到它们之间有任何的联系。

而描述文件正是把这些资源整合到一起的集合。

一个描述文件包含:

  • 一个 App ID

  • 开发或发布证书

  • 一组可安装该应用的设备列表(非必有)

描述文件会被打包到应用中,描述该应用的 App ID、持有的发布证书、以及能被哪些设备安装。

描述文件与证书一样,也分 开发发布 两大类型。其中,发布又被细分为Ad HocApp StoreEnterprise类型。

还记得前面说的 4 种发布方式吗?它们和描述文件的类型是一一对应的。

在打包的第一步选择了一个发布方式后,第二步就必须要选择相应的描述文件。

生成一个描述文件的步骤,就是选择一个类型,然后在开发者账号下的 ID、设备、证书资源池中选出资源,将它们整合到一起。

最后,我们用更直观的图来表述描述文件与安装方式、发布方式之间的关系:

iOS打包发布那些事儿

图 7 描述文件与安装方式、发布方式之间的关系

至此,我们已经大致了解了开发者账号和它管理的 App ID、证书、设备和描述文件,能够完成打包的第二步了。

接下来就是第三步编译和签名,我们重点关注签名。

签名与证书紧密相关。

为了更好的了解签名的原理和作用,我们将从证书开始讲起。

五、证书的生成

上一节讲过证书的生成步骤:

  1. 借助 keychain 在本地生成一个 CSR 文件

  2. 通过开发者账号将 CSR 上传至 Member Center

  3. 从 Member Center 下载证书

但看这个描述,我们根本无法得知每一步的原理和目的。比如:CSR 是什么,有什么用;上传 CSR 成功为什么能生成一个证书?这中间 Apple 又做了什么?

相信这些问题在这一小节结束后,你会知道答案。

1. 生成 CSR 文件: Keychain -> 证书助理 -> 从证书颁发机构请求证书

iOS打包发布那些事儿

图 8 生成 CSR 文件

CSR(Certificate Signing Request)文件是用 keychain 生成的,包含了请求证书者的个人信息的,用于向 Apple 证书颁发机构 (Apple Worldwide Developer Relations Certification Authority,为了简单理解,后文统称Apple Root CA) 申请证书的一个文件。

iOS打包发布那些事儿

图 9 CSR 文件的内容

想象一个场景:如果你去银行办理一张储蓄卡,那么银行就会要求你提供身份证,并填一份申请单,添上姓名、籍贯、常用住址等个人信息。

我们简单做一下类比:Apple Root CA 就相当于银行,证书相当于储蓄卡,CSR 文件就相当于储蓄卡的申请单。

生成 CSR 的时候发生了什么?

  1. 通过非对称加密,在本地生成了证书的公钥和私钥,保存在 Keychain 中(虽然与非对称加密的方式并不一致,但为了便于理解,我们把私钥类比成储蓄卡密码)

  2. 将公钥和个人信息一起组合形成了 CSR

这里插播一点对非对加密的简单理解:通过非对称加密生成的一对公钥和私钥,它们能互相解密出经过对方加密后的信息,并且也只有它们才能解密。

如果我们将 + 和 - 分别定义为加密和解密,那么:

iOS打包发布那些事儿

图 10 非对称加密

2. 通过开发者账号将 CSR 上传至 Member Center

成功后,我们就能在 Member Center 上下载证书了。

回到办理银行卡的流程:你将身份证、申请单交给工作人员,工作人员确认你本人和身份证相符,然后经过一系列的操作,最终会把办理好的银行卡交给你。

银行卡中是包含了你的个人信息的,因为办理很多的业务,都需要你本人携带身份证,并保证和开户信息一致。

这正是对应了当前这一步。

类比于银行工作人员的一系列操作,Apple Root CA 在从 CSR 到证书的过程中做了什么呢?

首先,Apple Root CA 是有一个由自己颁发的证书的 (CA 证书)。同样,这个证书也有它对应的公钥和私钥。

当我们将 CSR 传给 Apple Root CA,它会在验证身份之后,后用 CA 证书的私钥,对公钥和部分个人信息做加密,然后连同 CSR 中的公钥一起,形成证书,并记录在 Member Center 中。

iOS打包发布那些事儿

图 11 证书生成的原理

3. 从 Member Center 下载证书

下载证书到本地并安装。由于证书中包含证书的公钥,我们本地保存着证书的私钥,所以它们在 Keychain 中可以匹配得上:

iOS打包发布那些事儿

图 12 安装证书到本机

六、签名

加密应用的内容

打包的第三步:编译和签名。对应用签名,就是用证书的私钥加密应用的内容。签名会一并打包到应用中。

签名是打包的必需步骤。

签名需要证书的私钥。

证书的私钥保存在证书申请人的 keychain 中。

iOS打包发布那些事儿

图 13 App 的签名

因此:

  • 作为非证书申请人,如果你想在本地打包,则需要向证书申请人请求私钥。

  • 作为证书申请人,请像保护银行卡密码一样保护私钥,尽量不分发私钥。分发私钥意味着其他人可以以你的名义打包和发布应用。

至此,我们已经介绍完了打包的核心步骤。

那么我们为什么需要证书和签名呢?

七、证书和签名的作用

用证书验证签名,从而保证 App 来源可信

前面我们讲了签名和证书的生成过程,这里终于到了展现它们用处的时候了。

我们将通过 2 步验证,最终相信应用的可靠。

首先我们来回顾前面的内容:

  • 描述文件中包含有证书

  • App 中包含有描述文件和签名

除此之外,iOS 设备默认装有并信任 Apple Root CA 证书。

iOS打包发布那些事儿

图 14 iOS 设备上的 App 和 Apple Root CA 证书

下面我们开始验证:

1. 用 Apple Root CA 证书,验证应用证书的有效性

应用证书的签名,是由 Apple Root CA 的私钥加密应用证书的公钥和一些个人信息得到的。

如果用 Apple Root CA 证书中的公钥,能解密应用证书的签名得到应用证书上公钥,则能证明应用证书是由 Apple 颁发的。

iOS打包发布那些事儿

图 15 验证 App 证书的有效性

2. 用验证过的应用证书,验证应用签名的有效性

应用签名,是由应用证书的私钥加密应用内容得到的。

如果用应用证书中的公钥,能解密应用签名得到应用的内容,则能证明签名有效,应用可信。

iOS打包发布那些事儿

图 16 验证 App 签名的有效性

八、不是总结的总结

通过以上内容,我们了解到 iOS 应用打包发布的流程,和证书体系。

在这里,我刻意的没做总结。

开篇的那些问题,大家找到答案了吗?

作者介绍

王叁,ThoughtWorks 软件开发工程师,专注于 web 和 mobile 领域。

本文转载自 ThoughtWorks 洞见

原文链接

https://insights.thoughtworks.cn/ios-package-release/