我们在日常开发中经常会遇到如下问题

团队成员一不小心 Revoke 了证书导致所有的开发小伙伴需要重新下载证书

每次提交 App Store 审核需要重复【修改证书】-【打包】-【iTunes Connect】-【发布】等一系列动作

真的是不厌其烦,让人抓狂。这个时候,幸好 Fastlane 来了,看他怎么来拯救我们吧。在开始我们的教程之前,笔者先做个澄清,fastlane 不是什么:

  • fastlane 不是一个工具,而是一系列工具的集合。比如 match 工具能管理证书,deliver 能提交 APPStore 审核。所以我们在使用 fastlane 的时候更多的是和它的工具集打交道。
  • fastlane 内部的工具不是新写的,而是调用 Mac 本身的命令,只不过是实现了自动化而已。比如 gym 工具只是 xcodebuild 工具的一个封装,如果你会 xcodebuild,那 gym 对你来说小菜一碟。
  • fastlane 本身没有一套特殊语法,使用的 Ruby 语言,相信使用过 cocoapods 的同学应该很容易上手。

安装完 fastlane 并调用 fastlane init 后,目录结构大概如下所示

fastlane

具体的安装和初始化,本文稍后会详细讲述,先带大家分析一下安装后的 fastlane 的目录结构。红色区域就是多出来的文件。本项目是笔者的一个 APP Store 上线项目,大家可以点击这里获取:https://github.com/kysonzhu/wallpaper

Gemfile 告诉我们 fastlane 依赖的 gem 以及版本等其他信息。这个跟本文主题不大,笔者就不详细描述了。

fastlane 文件夹里的 Appfile 看文件也知道,里面是关于本 App 的信息的;Fastfile 则是 fastlane 的最主要的文件,在这个文件中可以编写我们需要使用的各个工具的顺序、方式等。

这里我们先看一个已经写好的 fastlane 的内容:

default_platform(:ios)

platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane do
    # add actions here: https://docs.fastlane.tools/actions
    match(
        git_url: "https://github.com/zjh171/fastlaneProvingProfile",
        type: "appstore" ,
        readonly: true
        )
    gym(
        scheme:"Wallpaper",
        export_method:"app-store",
        output_directory:"./build",
        archive_path:"./Archive"
        )
  end
end

这里我们只需要关注 match 和 gym 这两个工具以及括号后的内容。match 工具是我们本文开头描述的用于同步开发小伙伴证书的工具,而 gym 则是 xcodebuild 工具的封装,它指定了打包的目录以及打包的类型。保存该文件并执行 fastlane custom_lane 后我们可看到。

打包产物

这就表明我们打的 App Store 包已经生成了。目录就是我们指定的 output_directory 对应的目录。当然大家也不难猜想到,如果要让 fastlane 实现自动提交到 App Store 审核,还需要在 gym 后面加上我们需要的工具。这里先卖个关子,稍后告诉大家。下面笔者就详细的介绍一下 fastlane 的使用。

安装

执行命令 sudo gem install fastlane --verbose 即可,安装完成后检查一下是否安装成功输入 fastlane --version 看是否有版本号显示。

fix:出现错误

ERROR:  While executing gem ... (Errno::EPERM)
    Operation not permitted - /usr/bin/commander

OSX 10 后没权限,可以执行

sudo gem install -n /usr/local/bin fastlane

初始化

输入命令fastlane init会看到如下选项:

What would you like to use fastlane for?
1\. Automate screenshots
2\. Automate beta distribution to TestFlight
3\. Automate App Store distribution
4\. Manual setup - manually setup your project to automate your tasks

这四个选项的意思是

  1. 自动截屏。这个功能能帮我们自动截取APP中的截图,并添加手机边框(如果需要的话),我们这里不选择这个选项,因为我们的项目已经有图片了,不需要这里截屏。
  2. 自动发布 beta 版本用于 TestFlight,如果大家有对 TestFlight 不了解的,可以参考王巍写的这篇文章:TestFlight——完美的iOS app测试方案
  3. 自动的 App Store 发布包。我们的目标是要提交审核到 APP Store,按道理应该选这个,但这里我们先不选,因为选择了以后会需要输入用户名密码,以及下载 meta 信息,需要花费一定时间,这些数据我们可以后期进行配置。
  4. 手动设置。

选择第 4 个后一路回车即可,我们会看到生成了我们熟悉的 fastlane 目录,该目录下包含了 Appfile 和 Fastfile。我们打开这两个文件。

Appfile

# app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app
# apple_id("[[APPLE_ID]]") # Your Apple email address

# For more information about the Appfile, see:
#     https://docs.fastlane.tools/advanced/#appfile

发现里面没有任何信息(“#”在ruby里是注释,所以里面没有任何信息)注释的部分中,app_identifier 用于指定 APP 的bundle id,apple_id 指的是你的 AppleID。

Fastfile

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane do
    # add actions here: https://docs.fastlane.tools/actions
  end
end

这个文件的信息稍微多一点,而且我们也更熟悉了,语法跟 cocoapods 很像,而且我们在文章开头已经稍微做了一些介绍,发现在lane :custom_lane do 后面是空的。其实意思也就是说,这里任何操作都没有执行。

运行

虽然这是个什么都没有做的 fastlane 项目,但其实我们可以运行了,执行fastlane custom_lane命令,我们可以看到如下输出:

fastlane detected a Gemfile in the current directory however it seems like you don't use `bundle exec` to launch fastlane faster, please use
 $ bundle exec fastlane custom_lane
//此处省略多行
fastlane.tools finished successfully

大致意思就是,我们可以使用命令 bundle exec fastlane custom_lane代替 fastlane custom_lane,这样会执行的更快。最后的 fastlane.tools finished successfully 表示执行成功了。

打包

提交审核的前一步是打包,也是最主要的一步 fastlane 中有专门用于编译、打包的命令 gym,我们加到lane :custom_lane do后看看会不会有问题。

gym展示

然后执行fastlane custom_lane我们会收到如下提示:

Select Scheme:
1\. Wallpaper
2\. AFNetworking
3\. Mangogo
4\. Masonry
5\. MJRefresh
6\. Pods-Wallpaper
?

毫无疑问我们选择 1,其他的都是我们调用的三方库。但聪明的读者肯定在想,这个 Scheme 是否能在 fastlane 文件中就设置好,省的这里在自己选择。是的,这就是文章开头提到的

gym(
    scheme:"Wallpaper",
    export_method:"app-store",
    output_directory:"./build",
    archive_path:"./Archive"
    )

其中 scheme:"Wallpaper", 的含义。其他的参数也就不一一赘述了。读到这里,相信大部分读者已经对 fastlane 的原理一清二楚了。其实所谓的会用 fastlane 也就是会用里面的各种工具而已。我相信大家选完 Scheme 后还没到打包这一步,应该已经出现了错误提示,错误应该就是大家都非常熟悉的证书问题;当然,如果读者够侥幸,证书已经设置好了,并将 output_directory、archive_path 设置好了,那就能生成对应的对应的 IPA 包。但相信成功的读者应该寥寥无几,这个时候就要使出我们的大杀器 match。

证书管理

fastlane 中能管理证书和签名的工具其实还有 sigh 以及 cer,那为何笔者要给大家推荐 match 呢,原因已经在文章开头指出了,对于多人开发时出现的证书错乱问题 match 可以很好的处理。它将开发人员的证书提交到一个 git 仓库进行集中处理,在有新的成员加入开发时候,只需要运行一两条命令。下面我就详细讲一下其实现过程吧:

  1. 创建一个仓库(空仓库或者现有仓库都可以,但建议大家使用一个空仓库专门处理证书),这里笔者的仓库地址是:https://github.com/zjh171/fastlaneProvingProfile
  2. 在终端运行fastlane match init可以看到需要我们输入giturl地址,我们将地址拷进来即可。

git 地址输入位置

输入地址后我们会看到如下提示:

You can now run `fastlane match development`, `fastlane match adhoc`, `fastlane match enterprise` and `fastlane match appstore

我们按照提示生成 development 和 App Store 证书,然后会在 Xcode 中发现生成的证书以及 Provision Profile 文件。我们在 Xcode 中设置好即可。

证书列表

接下来,我们将 match 添加到 fastlane 文件中,如下:

添加mach的代码

当然,这个文件我们已经在文章开头看过了,是不是再次感觉豁然开朗。回到命令行,我们再次执行 fastlane custom_lane 发现我们可爱的 IPA 包已经打包完毕。

提交App Store审核

终于到了最令人激动的提交 App Store 时刻了。我们要使用的工具是 deliver。聪明的你应该已经知道,第一步肯定是要调用fastlane deliver init,这里会让我们输入 APPle ID ,输入以后就看到我们的项目文件夹发生了变化:

最终的产物

接着,我们修改一下 fastfile 文件,添加 deliver,因此我们最终版的 fastlane 文件是这样的:

lane :release do
        # 增加build版本号
      increment_build_number
      match(
        git_url: "https://github.com/zjh171/fastlaneProvingProfile",
        type: "appstore" ,#can be appstore,adhoc, development,enterprise
        app_identifier:"cn.kyson.wallpaper",
        username:"zjh171@qq.com",
        readonly: true
        )
      # 编译代码
    gym(
        scheme:"Wallpaper",
        export_method:"app-store",
        )
    # 发布到Apple Store
    deliver
  end

可以看到,大部分配置跟以前一样,只做了 lane 名的改变,还有添加了increment_build_number这一行。increment_build_number的作用是防止本地版本的 build 号比 App Store(或上次) 低而做的自动增长版本号的处理。当然加了这几句还需要在 Xcode 中做相应处理:

Xcode参数

最后在命令行中输入fastlane release,等待大概十几分钟就可以看到成功的提示了。然后我们进入iTunes Connect,确认一下:

iTunes Conect发布页面

确实是已经在审核状态。如果大家想实现“一键审核”可以给 deliver 带上参数 submit_for_review。这样就真正实现了一键提交App Store 审核。至此,我们的一键打包审核流程完美收工。

注意点

笔者从开始研究 fastlane 到完全跑出来大概花了三天时间,期间遇到了很多问题,走了很多弯路,总结一下,希望对读者有一定帮助

  • fastlane 的初始化命令是fastlane init,不需要加 root 权限,也就是sudo fastlane init是不需要的,如果使用了 sudo 会对后面的各个操作造成很大影响,比如项目文件(Workspace 后 Project 文件)会锁定不能操作,还会引起打包失败
  • 很多刚接触 fastlane 的同学会一不注意就被 fastlane 上的各种命令整的晕头转向,例如 sync_code_signing 命令,其实是 match 命令的另外一种写法;build_app 命令其实是 gym 的别名。因此大家在学习 fastlane 的时候只需要学习本文介绍的命令,大部分情况下已经够用。如果对一个命令的用法不熟悉,可以通过fastlane action查找,例如fastlane action match