使用 fastlane 实现对 iOS Multi-Target 的一键打包部署

使用 fastlane 实现对 iOS Multi-Target 的一键打包部署_第1张图片

1. 前言

iOS App 的发布流程繁琐,网络问题频出,每次发布都可以说是开发者的噩耗,如果碰到像我一样每次都要分别发布到多个苹果开发者账号下的 iTunes Connect 的情况,可以说简直就是被谋杀了一遍。
幸好,最近发现了 fastlane 这个神器,可以将所有关于 iOS App 发布的流程配置成工作流,实现一键发布!
从此发布不再是噩梦。

PS:如果你的 App 只有一个 target,也只需要发布到一个开发者账号下,那么直接参考官方教程即可,很简单,容易上手。

1.1 开发环境

  • macOS Sierra : 10.12.3 (16D32)
  • Xcode : 8.2.1 (8C1002)

1.2 工具

  • fastlane

2. fastlane 简介

fastlane 官网已经讲得非常清楚,fastlane 是一个关于 App 发布的工具集,除了提供 iOS 发布相关工具外,也支持 Android App 发布。根据官网显示,目前已经为开发者节省了6158597 个小时,被誉为开发者的救星也不为过。


使用 fastlane 实现对 iOS Multi-Target 的一键打包部署_第2张图片
使用 fastlane 实现对 iOS Multi-Target 的一键打包部署_第3张图片

3. 实现步骤

3.1 fastlane 初始化

首先安装 fastlane(若安装失败,fastlane 主页提供另外两种安装方式)

$ sudo gem install fastlane -NV

在 xcode 工程目录下,执行
$ fastlane init

执行过程中,会提示输入苹果账号密码,自动下载 App 元数据等信息,由于我们的 xcode 工程中使用的是 mutil target,但 fastlane init 只能处理一个 target 的信息,所以我们按照提示输入任意一个 target 的相关信息就行了,后面通过修改配置文件来实现 mutil target 的支持。

fastlane 初始化完成后,会在 xcode 目录下自动生成以下文件:

  • metadata 目录:存放 App 元数据,包括 App 简介,Icon,Copyright 等
  • screenshots 目录:顾名思义,存放 App store 中的截图
  • Appfile:用于指定 app_identifier, apple_id, team_id;本文中每个 target 都有自己的 app_identifier, apple_idteam_id
  • Deliverfile:用于指定跟 App 版本发布相关的信息,除了 apple_identifier 外,还包括 submit_for_review, automatic_release 等可配置项,基本覆盖 iTunes Connect 里面的所有选项
  • Fastfile:用于编写逻辑脚本,使用 ruby 语言,例如首先执行 cocoapods 更新第三方依赖库,然后执行 pem 更新相关证书,接着通过 gym 来编译并打包 ipa 文件,最后通过 deliver 发布到 iTunes Connect 中,并提交审核。具体逻辑按照开发者需求自行设计。

3.2 配置文件修改

fastlane 默认支持一个 target,对于这类型需求,只需要按着 fastlane 提供的官方教程学习即可,很简单。但对于 mutil target,并且每个 target 对应不同的开发者账号的情况,配置起来稍微有点不同。

3.2.1 .env文件配置

fastlane init 后默认生成的文件中并没有.env 文件。此文件的作用理解起来很简单,说白了就是自定义临时变量,供 Appfile, DeliverfileFastfile使用。
理解原理后,使用起来就简单了,就是有几个 target,就创建几个.env 文件,提供不同的变量值,供不同 target 编译打包上传时使用。
例如,针对 target A 和 target B,分别创建 .env.targetA 和 .env.targetB 两个文件,内容分别是

使用 fastlane 实现对 iOS Multi-Target 的一键打包部署_第4张图片

其他配置文件可通过 ENV['APP_IDENTIFIER'] 来读取变量值
$ app_identifier ENV['APP_IDENTIFIER']
fastlane 调用时,通过添加参数 --env 来指定待读取的 .env 文件
$ fastlane release --env targetA
$ fastlane release --env targerB

3.2.2 Appfile配置

创建完所有 target 的 .env 文件后,Appfile 的设置就变得很简单了

    # The bundle identifier of your app
    app_identifier ENV['APP_IDENTIFIER']
    
    # Your Apple email address
    apple_id ENV['APPLE_ID'] 
    
    # Developer Portal Team ID
    team_id ENV['TEAM_ID']  

3.2.3 Deliverfile配置

由于涉及到 iTunes Connect 中所有可配置项,Deliverfile 的配置项有点多,具体可查看官网说明。这里我们对一些常用的配置进行修改:

    # The bundle identifier of your app
    app_identifier ENV['APP_IDENTIFIER']
    
    # your Apple ID user
    username ENV['APPLE_ID']
    
    # 元数据的路径
    metadata_path ENV['METADATA_PATH']
    screenshots_path ENV['SCREENSHOTS_PATH']
    
    #App store 中待发布的 App 版本,若每个 target 的版本号不同,可以通过.env 文件来分别定义
    app_version "3.3"
    
    #下载 metadata 及 screenshots 时直接覆盖,不询问
    force true
    
    #不覆盖 iTunes Connect原有截图
    skip_screenshots true
    #自动提交审核
    submit_for_review true
    #审核通过后立刻发布
    automatic_release true
    
    #新版本修改记录
    release_notes({
        "en-US" => "1) upgrade test line 1\n2) upgreade test line 2",
        "zh-Hans" => "1) 升级测试第一行\n2) 升级测试第二行"
    })
    
    #App 加密算法使用情况及广告相关配置
    submission_information({
        #Export Compliance
        export_compliance_available_on_french_store: "false",
        export_compliance_contains_proprietary_cryptography: "false",
        export_compliance_contains_third_party_cryptography: "false",
        export_compliance_is_exempt: "false",
        export_compliance_uses_encryption: "false",
        export_compliance_app_type: nil,
        export_compliance_encryption_updated: "false",
        export_compliance_compliance_required: "false",
        export_compliance_platform: "ios",
    
        content_rights_contains_third_party_content: "false",
        content_rights_has_rights: "false",
    
        #Advertising Identifier
        add_id_info_limits_tracking: "false",
        add_id_info_serves_ads: "false",
        add_id_info_tracks_action: "false",
        add_id_info_tracks_install: "false",
        add_id_info_uses_idfa: "false"
    });

3.2.4 Fastfile配置

在对 Fastfile 进行配置前,我们先了解下 lane.
lane可以理解为 fastlane 的执行脚本,一个Fastfile 里可以编写任意个lane,每个lane都可以独立运行,也可以嵌套运行。话不多说,直接上代码:

首先,编写一个编译并上传到 iTunes Connect 的 lane,名称为 deploy.

desc "Deploy one target"
lane : deploy do
    gym(scheme: ENV('SCHEME_NAME'], silent: true)
    deliver
end

然后,编写另外一个lane,名称为 deploy_all, 用于编译并上传所有 target.

desc "Deploy multi targets"
lane :deploy_all do
    cocoapods
    sh "fastlane deploy --env targetA"
    sh "fastlane deploy --env targetB"

最后,只需要在 xcode 工程目录下执行
fastlane deploy_all
即可实现 iOS App Multi targets 的一键编译打包并上传。

4. 坑!

4.1 .env 为隐藏文件

Finder 默认不显示隐藏文件,创建 .env 文件后,若需查看,需要执行两条命令来开启隐藏文件的显示:

$ defaults write com.apple.finder AppleShowAllFiles -boolean true;
$ killall Finder

4.2 等待输入密码时崩溃退出

fastlane 在等待密码输入时貌似不大稳定,有50%以上机会崩溃,所以,建议把密码写到.env 文件中。

4.3 版本修改记录上传不成功

  1. Deliverfile 中,通过 release_notes 来设置版本修改记录
  2. 同时,不要设置skip_metadata选项
#新版本修改记录
release_notes({
    "en-US" => "1) 升级测试\n2) 升级测试第二行",
    "zh-Hans" => "1) 升级测试\n2) 升级测试第二行"
})

4.4 自动提交审核的原理

通常开发者上传 .ipa 文件到 iTunes Connect 后,需要等待一段时间后才能选择新上传的 build,然后才能提交审核。那么 fastlane 是如何做到自动提交审核的呢?答案就是,等待,并且每分钟检查一遍 build 是否就绪。

5. 总结

苹果把 App 发布流程设置得如此反人类,虽说是有它的道理与作用,作为开发者也只能遵循。不过「道高一尺魔高一丈」,作为一名程序猿,对于这种「重复体力投入」性质的工作,当然是要通过工作流来实现它,解放双手,节省时间多陪女票。

你可能感兴趣的:(使用 fastlane 实现对 iOS Multi-Target 的一键打包部署)