iOS 进阶学习

iOS使用fastlane实现自动化打包

2018-11-14  本文已影响3426人  小盟城主

一、fastlane简介

fastlane是一套使用Ruby写的自动化工具集,用于iOS和Android的自动化打包、发布等工作,可以节省大量的时间。

fastlane官网:
https://fastlane.tools/

fastlane的官方Github:
https://github.com/fastlane/fastlane

fastlane文档说明:
https://docs.fastlane.tools/

使用fastlane前,确保你已经可以使用Xcode手动打包成功(说明你已经配置好证书)

证书配置

1. 配置环境

1.安装HomeBrew

# 查看电脑有没有安装  HomeBrew 没有的话进行下面的安装
brew -v

#安装
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
#更新到最新版
brew update
#更新包
brew upgrade

2.安装ruby

# 查看电脑是否已经安装ruby 没有的话进行下面的安装
ruby -v  

#安装
brew install ruby

#查看版本
ruby -v  
# 例如我的电脑的ruby版本为
# ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin17]

3.安装fastlane

确保你的电脑上已安装最新版本的Xcode命令行工具(Xcode command line tools)

xcode-select --install

如果没有安装,会弹出对话框,点击安装。如果提示xcode-select: error: command line tools are already installed, use "Software Update" to install updates表示已经安装

开始安装fastlane

#安装
gem install fastlane -NV

或者使用

brew cask install fastlane

安装完之后

# 确认下是否安装完成和当前使用的版本号
fastlane -v 

# 我的目前电脑版本
# fastlane installation at path:/Users/hf/.rvm/gems/ruby-2.2.3/gems/fastlane-2.108.0/bin/fastlane
# -----------------------------
# [✔] 🚀 
# fastlane 2.108.0

二、使用fastlane

创建一个测试demo,我创建的是HFMyTest
我的项目的bundle id为www.hf.mytest,这个bundle id需要在开发者中注册provisioning profile
同时注意设置schemeShared,不然fastlane init的时候会失败,一般默认是选择Shared的,可以不用去管

设置方法为:A、打开项目的Manage Schemes

scheme1
B、勾选上Shared
scheme2
  1. 先cd到项目路径
cd /Users/hf/MyTest/HFMyTest/Example
  1. 初始化fastlane
fastlane init 
fastlane init

可以看见有四个选项

  1. 自动化截图
  2. 将测试版分发自动化到TestFlight
  3. 自动上传、发布到App Store
  4. 手动设置 - 手动设置您的项目以使您的任务自动化

3. 我这里选择的是3

select scheme
  1. 可能需要你去select scheme,注意这里面的sheme不是你的项目名,例如我的项目名为HFMyTestsheme就是上面介绍的勾选的Manage ShemesHFMyTest-Example,所以这里选择1

    select sheme
  2. 由于选择3是要发布都AppStore,所以接下来输入用户的app id,这个id应该是具有开发者资格的账号
    输入id之后接下来输入id的密码

Apple ID
  1. 输入账号和密码后
    如果开发者账号上没有对应的bundle id的App,会提示是否创建一个新的App,这里我们选择否(n),因为这样快速创建的App设置的信息有限


  2. 接下来等待加载,按照步骤回车就可以完成初始化


    初始化完成
  1. 初始化完成后,打开项目目录


    HFMyTest
  2. 发现项目中多出了fastlane目录,通过sublime或者文本编辑打开Appfile和Fastfile

app_identifier("www.hf.mytest") # The bundle identifier of your app
apple_id("webmaster@xspcf.com") # Your Apple email address

itc_team_id("118090429") # App Store Connect Team ID
team_id("MQJL2427R9") # Developer Portal Team ID

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

  1. 上面这个Appfile默认已经初始化好了,不用再去操作
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do
  desc "Push a new release build to the App Store"
  lane :release do
    increment_build_number(xcodeproj: "HFMyTest.xcodeproj")
    build_app(workspace: "HFMyTest.xcworkspace", scheme: "HFMyTest-Example")
    upload_to_app_store(skip_metadata: true, skip_screenshots: true)
  end
end

  1. 以上Fastfile代码中,默认已经设置为上传到AppStore的操作
    release为lane的名字,在执行lane的时候会用到,你可以为lane取任意的名字,也就是release可以取其它的,如appRelease
    build_app用来编译app,你可以为其指定更多的的参数
    打开终端cd到项目目录,运行就可以打包发布到
    AppStore
    使用以下命令来执行这个lane:
cd /Users/hf/MyTest/HFMyTest/Example
fastlane release

由于上面我们选择了否(n),也就是现在AppStore上面还没有我们这个HFMyTest这个app,所以上面的操作会最终失败的

上传AppStore失败
  1. 但是这时候打开HFMyTest本地目录会发现里面会有打出的ipa包
    HFMyTest

三、自定义Fastfile

我们知道上面的Fastfile是我们在fastlane init初始化时4个选择中选择了3发布到AppStore,所以生成的Fastfile的功能是只具有发布到AppStore的功能

打开本地的HFMyTest目录
删除下面三个文件

HFMyTest

然后重新运行一次初始化

cd /Users/hf/MyTest/HFMyTest/Example
fastlane init

然后在四个选项中选择第二个


TestFlight

然后按照开始的步骤来,最终的到的Fastfie如下

default_platform(:ios)

platform :ios do
  desc "Push a new beta build to TestFlight"
  lane :beta do
    increment_build_number(xcodeproj: "HFMyTest.xcodeproj")
    build_app(workspace: "HFMyTest.xcworkspace", scheme: "HFMyTest-Example")
    upload_to_testflight
  end
end

这个Fastfile主要是用于发布到TestFlight进行测试的,
所以我们可以再终端运行

fastlane beta

进行发布到testflight,和上面的一样,AppStore是上面没有创建对应的app,这个运行最终会失败。

Fastfile自定义,它的格式如下

···
# 自动更新fastlane 工具
# update_fastlane
 
#需要的fastlane的最小版本,在每次执行之后会检查是否有新版本,如果有会在最后末尾追加新版本提醒
fastlane_version "2.100.0"
 
#默认使用平台是 ios,也就是说文件可以定义多个平台
default_platform :ios
 
platform :ios do
  before_all do
    # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
 
  end
 
  desc "Runs all the tests"
  lane :test do
    scan
  end
 
  desc "提交一个新的Beta版本到 Apple TestFlight"
  desc "This will also make sure the profile is up to date"
  lane :beta do
    # match(type: "appstore") # more information: https://codesigning.guide
    gym(scheme: "app_ scheme") # Build your app - more options available
    pilot
 
    # sh "your_script.sh"
  end
 
  desc "部署一个新版本到App Store"
  lane :release do
    # match(type: "appstore")
    # snapshot
    gym(scheme: "app_ scheme") # Build your app - more options available
    deliver(force: true)
    # frameit
  end
 
  # 你可以定义自己的lane
 
  #执行lane成功后的回调
  after_all do |lane|
    # slack(
    #   message: "Successfully deployed new App Update."
    # )
  end
 
  # 如果流程发生异常会走这里并终止
  error do |lane, exception|
    # slack(
    #   message: exception.message,
    #   success: false
    # )
  end
end
fastlane主要的操作就是action,常用的action有

scan

release情况下无法正常运行scan,需要手动去Build Setting中更改enable Testability 在release 下的状态,改为 yes才可以运行。但是官方不建议做release下开启,Test一般在development configuration 下执行。

gym

常用参数:
scheme :指定打的哪个scheme
project :指定project (未使用cocopods)
workspace :指定workspace (使用cocopods)
clean :打包前clean
xcargs : 附加一些参数传递给xcodebuild 如: xcargs: 'DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"',
export_method :出包方法 app-store, ad-hoc, package, enterprise, development
configuration : 指定构建App的配置  Release、Debug、自定义
output_directory : 输出目录
output_name :输出名称
include_symbols :是否包含调试符号
include_bitcode :是否开启bitcode

pilot

#用于发布**testflight**内部测试,属于**testflight action**的别名
#常用参数:
#ipa :要提交的包地址
#team_name、team_id :如果有多个team 用于区分team
#skip_waiting_for_build_processing : 在提交完成后的等待是否跳过,一般跳过changelog
pilot(
  ipa : '../xx.ipa'
)

deliver

#用于**直接发包到appstore**,可以选择跳过图片和元数据上传,只提包,后面再配图和数据:如下 skip_screenshots 和  skip_metadata 参数
 deliver(
    ipa: "#{OUTPUT_DIRECTORY}" + "/" + "#{IPA_NAME}",
    skip_screenshots: true,
    skip_metadata: true
)

四、插件的使用

  1. 查看所支持的插件
fastlane search_plugins
  1. 查看某种插件
fastlane search_plugins [query] #query为插件名
  1. 添加插件
fastlane add_plugin [name] #name 为插件名
  1. 插件使用实例:上传ipa包至蒲公英pyger
    首先添加pyger插件:
# cd 到项目目录
cd /Users/hf/MyTest/HFMyTest/Example
# 安装插件
fastlane add_plugin pyger 

编辑FastFile,添加以下信息

desc "打包并上传测试版至蒲公英"
  lane :beta_pgyer do 
    #编译并导出ipa包
    gym(
      clean: true,
      scheme: "scheme_name",
      export_method: "development",
     )
    #上传至蒲公英
    pgyer(
      api_key: "", 
      user_key: "", 
    )
 end

然后终端输入

fastlane beta_pgyer

就可以上传包到蒲公英
其中蒲公英的api_key和user_key需要用户去注册蒲公英账号,然后去获取


蒲公英

在Fastfile中可以自定义一个有外部传进来参数的方法options,这个options类似于一个字典,可以传入不同的key来获取value,例如通过options[:myKey] 就可以获取value

lane :myTest do |options|
    myTestStr = options[:key1]
end

传入options的值

fastlane myTest key1:myValue1 key2:myValue2
# 传入了两个数字
{"key1": myValue1,"key2":"myValue2"},
# 获取数值方式为
options[:key1] = myvalue1

在Fastfile中设置了increment_build_number进行自动build数字增加,作用是防止本地版本的build号比App Store(或上次)低而做的自动增长版本号的处理,需要先在Xcode中配置如下

incrementBuild

下面给出我的一套写好的Fastfile

# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself



################## READ  FIRST ##################

######## 使用方法1 自定义version和build #########
###### fastlane iosDebug version:1.0.1  build:1 ######

######## 使用方法2 不写version和build 这时build会根据之前的build+1 #########
###### fastlane iosDebug  ######

###如果需要上传到蒲公英,请运行前先安装插件安装蒲公英的fastlane add_plugin pgyer ###


default_platform(:ios)   # 设置默认的平台为ios

############# 需要根据项目自定义设置 ############
APP_NAME = "HFMyTest"                # app的名字
APP_SCHEME = "HFMyTest-Example"  
APP_IPA_OUTPUT_DIRECTORY = "build/packages"    # 打包所保存的文件目录,可以不设置
# 配置蒲公英的apiKey 和 userKey 需要设置 
APP_PGYER_API_KEY = ""
APP_PGYER_USER_KEY = ""


######## 不用设置的 #####################
APP_XCODEPROJ = "#{APP_NAME}.xcodeproj"      # app的xcodeproj
APP_WORKSPACE = "#{APP_NAME}.xcworkspace"    # app的xcworkspace
APP_IPA_TIME = Time.now.strftime("%Y-%m-%d_%H:%M")  # 打包的时间
# APP_INFO_PLIST_PATH = './HFMyTest/HFMyTest-Info.plist'
APP_ENV_PREFIX = ""   # 打包完成后的包文件名字的前缀 区别release和debug



# 版本 build number++
def prepare_version(options)

    #增加version版本号
    if options[:version]
      increment_version_number(
        version_number: options[:version],
        xcodeproj: "#{APP_XCODEPROJ}",
      )
    else
      # 可以不设置
    end

    
    #增加build号  只能是整数和浮点数
    if options[:build]
      increment_build_number(
        build_number: options[:build],
        xcodeproj: "#{APP_XCODEPROJ}",
      )
    else
      last_build = get_build_number(xcodeproj: "#{APP_XCODEPROJ}")
      now_build = last_build.to_i + 1
      increment_build_number(
        build_number: now_build,
        xcodeproj: "#{APP_XCODEPROJ}",
      )
    end
end


#统一的打包方法
def generate_ipa(exportMethod,configuration,options)
    
    # 设置version和build
    prepare_version(options)  

    app_version = get_version_number(xcodeproj: "#{APP_XCODEPROJ}")     # 得到最新的version
    app_build = get_build_number(xcodeproj: "#{APP_XCODEPROJ}")         # 最新的build
    # app包名
    app_ipa_name = "#{APP_NAME}_" "#{APP_ENV_PREFIX}_" + "#{APP_IPA_TIME}_" + "#{app_version}_" + "#{app_build}"
   
    #打包
    gym(
      clean: true,       # 打包前clean项目
      silent: true,      # 隐藏没有必要的信息
      scheme: "#{APP_SCHEME}",
      workspace: "#{APP_WORKSPACE}", 
      configuration: "#{configuration}",  # 环境
      export_method: "#{exportMethod}",   # app-store、ad-hoc、development、enterprise
      output_directory: "#{APP_OUTPUT_DIRECTORY}", #ipa的存放目录
      output_name: "#{app_ipa_name}", # 输出ipa的文件名
      # 生成的ipa文件是否包含symbols,这个文件是内存标记文件,用来定位错误信息的,有了这个安装包大小会变大
      include_symbols: true,
      # 生成的ipa文件是否包含bitcode,在本身项目中也可以配置
      include_bitcode: false,
      # keychain授权 Xcode9不允许访问钥匙串密码,所以我们需要手动开权限
      export_xcargs: "-allowProvisioningUpdates"
      )

end

platform :ios do
  # before_all就是先于所有lane执行的任务
  before_all do
       # 根据安装路径指定要使用的Xcode 
       xcode_select "/Applications/Xcode.app"
       # 超时失败,默认的timeout是10秒
       ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"
  end

  # lane  自定义的任务

  #debug包 option类似一个字典 option[:version] 取其中value值version
  lane :iosDebug do |options|
    APP_ENV_PREFIX = "debug_"
    generate_ipa("development","Debug",options)

    # 上传至蒲公英 在这之前请安装插件 fastlane add_plugin pgyer
    if APP_PGYER_API_KEY.length > 0 && APP_PGYER_USER_KEY.length > 0
      pgyer(
        api_key: "#{APP_PGYER_API_KEY}", 
        user_key: "#{APP_PGYER_USER_KEY}", 
      )
    end
  end

  # release发布包
  lane :iosRelease do |options|
    APP_ENV_PREFIX = "appstore_"
    generate_ipa("app-store","Release",options)
    # 上传至app-store
    deliver(
      force: true,              #是否跳过HTML验证报告,默认false
      skip_metadata: true,      #是否跳过上传metadata,默认false
      skip_screenshots: true    #是否跳过上传屏幕截图,默认false
    )
  end

  # testFlight包  
  lane :iosTestFlight do |options|
    APP_ENV_PREFIX = "adhoc_"
    generate_ipa("ad-hoc","Release",options)
    # 管理TestFlight的测试用户,上传二进制文件
    pilot
  end

  # 当lane执行完成之后进行哪些操作
  after_all do |lane|

  end

  error do |lane, exception|

  end

end
上一篇下一篇

猜你喜欢

热点阅读