Skip to content

macOS App IDs, Certificates & Profiles 基础和自动化管理 #39

Description

@WJCHumble

前言

在前面「macOS App 自动化分发 App Store 探索与实践」「一文带你读懂何为 macOS App 公证,以及如何自动化实现」 2 篇文章中,分别给大家介绍了 macOS 分发自动化实现相关的内容。其中,我们总是会提及证书、App IDs 和 Provisioning Profile 等相关内容,并且证书和 Profiles 在不同的分发渠道(网络或 App Store)都有所区分。

虽然,直接通过 Apple Developer 的账户(Account)后台可以查看前面提及的内容。但是,由于这个的前提是要求我们注册 Apple Developer Program(付费 688),所以,存在一定的使用之前的成本(费用),那么或多或少就有同学对此存在一定的盲区,以及在了解后也会遇到协作和管理的问题。

那么,今天本文也将会从证书、App IDs、Provisioning Profile 作为开始,带大家一起从理论基础出发,再到如何使用工具(fastlane match)实现自动化管理。

1 证书、App IDs、Provisioning Profile

Apple Developer 的账户(Account)后台,有专门用于查看 Certificates, Identifiers & Profiles 的页面,你可以在这里管理你的证书 Certificates、App IDs(Identifiers)和 Provisioning Profile:

下面,我们分别来看下这 3 者。那么,首先是 App IDs(Identifiers)。

1.1 App IDs(Identifiers)

App IDs(Identifiers),它是 Identifiers 的一种,用于使得你的 App、App Extension 或 App Clip 能够访问可用服务,以及可以在 Provisioning Profile 中标识你的 App。

也就是说,App IDs 是一个应用的唯一标识,是必须要创建的,它的命名遵循 reverse-domain 的风格,例如 com.domainname.appname。并且,我们可以通过查看 macOS 上 App 的包内容(应用程序->右键-> info.plist),例如 macOS 上的微信的 App IDs 会是 com.tencent.xinWeChat

1.2 证书 Certificates

然后,接着是证书 Certificates,证书分为这 2 类:

  • 软件 Software,包括用于应用(iOS、macOS 和 watchOS 等)代码签名、Apple Store 分发(Distribution)、安装包(Installer package)签名等证书
  • 服务 Services,包括苹果推送服务( Apple Push Notification service )、苹果支付处理证书(Aple Pay Payment Processing Certificate)等证书

并且,值得一提的是证书的创建使用的是一种 创建证书签名请求 的方式,这种方式遵循的非对称加密(RSA),它会在本地创建一对公用密钥和专用密钥(以下统称私钥 Private Key),其中,公钥用于加密证书,私钥是保存在创建者本地的钥匙串 KeyChain 中。

那么,如果你想将证书分享给别人使用,但是由于非对称加密的限制(证书是加密的),我们还需要提供解密证书对应的私钥,所以,通常情况下我们是在钥匙串中导出个人信息交换(.p12)文件,它会包含证书本身和解密它需要的私钥:

此外,关于各个证书的详细作用有兴趣的同学可以自行了解。这里,我们来看下软件 Software 证书中 macOS 开发和分发相关的 4 个证书:

  • Mac Development,用于 macOS 应用开发版本的代码签名处理,例如,如果你有一个 FEKit.app 文件没有经过应用的签名,则可以使用 codesign 命令进行签名:
codesign -s "Development" ./FEKit.app
  • Developer ID Application,用于 macOS 应用正式版本的代码签名处理:
codesign -s "Developer ID Application: Jingchang wu(xxxxxxxxxx)" ./FEKit.app
  • Mac Installer Distribution,用于对安装包(Install Package)进行代码签名以提交到 App Store

  • Mac App Distribution,用于对应用程序进行代码签名,以及配置分发 Provisioning Profile 用于提交到 App Store

1.3 Provisioning Profile

最后,则是 Provisioning(配置)Profile,Provisioning Profile 分为这 2 类:

  • 开发 Development,用于配置可以安装开发版本应用的设备有哪些,也就是在创建 Development 下的某类 Provisioning Profile 文件的时候需要填入测试设备的硬件 UUID(关于本机->系统报告)

  • 分发 Distribution,用于配置应用分发相关,例如提交 AppStore、使用 Apple Services 等

那么,对于 macOS 而言,我们则需要创建 **macOS App Development(配置开发版本应用的测试设备)、
Mac App Store(提交 AppStore)和 Developer ID(在网络上分发)**等 3 个 Provisioning Profile。

2 fastlane match 自动化管理

通常,我们一个项目会有多个开发者 Developer,那如何在多个开发者之间共享同一份 Mac Development、Developer ID Application 等证书或 Provisioning Profile 文件,就成为了一个比较琐碎的问题

所以,fastlane 提供了一个名为 sync_code_signing 的 Action 用于解决上面提及的这个问题,它的 alias 是 match,也就是我们可以通过 fastlane match xxx 之类的命令来完成证书和 Provisioning Profile 文件的维护(创建、更新)和拉取(同步到开发者本地),而这些操作则是使用的 Apple Store Connect API 提供的接口实现的。

其中,由于 fastlane 需要指定的可以用于存储证书和 Provisioning Profile 文件的地方,你可以使用 Git Repo、Google CloudAmazon S3 其中的 1 种作为存储的选择,这里我们选择用 GitLab 的 Repo。

那么,首先是在你的项目中执行 fastlane match init 命令,它会提示你要选择的存储方式:

这里我们选择 Git,然后需要输入 Repo 的地址,最后它会在当前项目路径的 ./fastlane 文件目录中创建 Matchfile 文件:

git_url("https://gitlab.com/xxxxx/xxxxxxxxxx.git")

storage_mode("git")

type("development") # The default type, can be: appstore, adhoc, enterprise or development

# app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
# username("user@fastlane.tools") # Your Apple Developer Portal username

可以看到,默认设置了 git_url 为前面输入的 Git Repo 的地址(以下统称 Match Repo),然后 storage_mode 设置的为 git,并且默认会设置 typedevelopment,这意味着在执行 fastlane match development --readonly 命令的时候会获取所有 development 相关的证书和 Provisioning Profile 文件(如果没有则会重新创建)。

由于,很多情况下我们使用 fastlane match <type> 相关的命令的时候,我们可能已经创建好了各类的证书和 Provisioning Profile 文件。所以,不能直接使用 fastlane match <type> 的命令,这样会给你撤销之前已创建好的这些文件并创建一个新的

因此,我们需要使用 fastlane match import 命令来将本地的证书(.cer)、个人信息交换(.p12)和 Provisioning Profile 文件手动导入到 Match Repo 中,例如我们需要把 Developer ID Application 相关的证书、p12、Provisioning Profile 文件导入:

1.首先,修改下之前的 Matchfile 文件的内容:

# 注意,默认为 master 分支
git_url("https://gitlab.com/xxxxx/xxxxxxxxxx.git")

storage_mode("git")
# 指定证书、.p12、Provisioning Profile 的类型
type("developer_id")
# 指定我们的 App IDs
app_identifier("com.xxx.xxxx")

2.接着,将本地的上面提及的文件在钥匙串中分别导出到文件系统中。

3.最后,使用 fastlane match import 命令,此时会让你输入各个文件所在的位置,然后需要输入密码用于证书的加密,也就是说其他人从 Match Repo 拉取的时候需要输入对应的密码用于解密,接着则还会让你输入 Apple Developer Program 账户来对这些文件进行验证,如果你不期望验证可以使用 --skip_certificate_matching true Option 来跳过这个步骤。

在完成上述文件的导入后,在 Match Repo 中可以看到新增了 /certs/developer_id_application/ 和 /profiles/developer_id/ 等 2 个目录结构,后续我们导入别的的证书(.cer)、个人信息交换(.p12)和 Provisioning Profile 文件则会一并添加到 /certs 或 /profiles 目录下:

certs
  |———— developer_id_application
        |__ xxxxx.cert
        |__ xxxxx.p12
profiles
  |———— developer_id
        |__ xxxxxxxxxxxxxxxxxxx.provisionprofile

然后,如果有同学在开发过程中需要使用到 Developer ID Application 相关的证书、私钥(.p12)和 Provisioning Profile 文件,则可以通过 fastlane match developer_id --readonly 命令获取这些文件到本地的钥匙串中,其中 --readonly 只拉取 Match Repo 中存在的 developer_id 相关文件,不会自动创建一个新的。

结语

通过阅读,对于之前一直没有接触过这方面知识的同学,我想已经对证书、App IDs 和 Provisioning Profile 等相关内容都或多或少有了一定的了解。并且,通过简单地了解 fastlane match 提供的能力,也可以让团队在这方面的协作效率和维护管理都得到了提高。此外,值得一提的是 fastlane match 提供了很多参数,来支持更多个性化的操作,例如过期自动创建、撤销指定类型的证书等,所以有兴趣的同学也推荐在文档中继续了解一番。

最后,如果文中存在表达不当或错误的地方,欢迎各位同学提 Issue ~

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions