在iOS开发人员社区中, fastlane是当今非常流行的工具。 与iTunes Connect交互需要非常繁琐的工作,并且通过自动执行大部分任务使其几乎没有痛苦。 我们将了解fastlane的总体概念,并学习如何通过一个命令为所有设备使用所有语言的屏幕截图。
为什么要快车道
“手工,重复的工作不值得我花时间。” 每个程序员在他的职业生涯中都至少考虑过一次。 但是,我们大多数人都不想花时间学习如何正确地自动化。 也许是因为我们很少执行这些任务,或者是因为我们认为现在没有足够的时间来处理它。
尤其是如果每次任务都是一样的,但任务却没有那么多,例如发布新版本或将构建分发给Beta测试人员。 但是,自动化这些任务当然是一个好主意。 您可能会忘记一步而不得不重新开始,或者,在处理Beta版本时,在分发新版本之前,将新设备添加到Developer Portal并刷新配置文件可能非常繁琐。
这就是fastlane的用处 。它可以使命令行自动化或在持续集成服务器上完全自动化,从而使您的分发管道自动化并最大程度地减少与Developer Portal和iTunes Connect的交互。
工具套件
fastlane不仅仅是一个工具。 在撰写本文时,它是十二个工具的集合,这些工具遵循Unix的哲学“做一件好事”。 当然,它们相互依赖并相互作用。
fastlane本身就是这些工具的包装,使开发人员能够定义工作流,也称为Lanes 。 每个工作流程都需要运行不同的工具。 例如,如果您要将预发行版本分发给测试人员,则无需为App Store创建屏幕截图。
安装
在开始使用fastlane之前,需要确保已安装Xcode 命令行工具 。 在命令行中,执行xcode-select --install
进行安装。 如果已经安装,您将看到一个错误。
fastlane本身就是Ruby宝石。 根据您的系统,您必须运行gem install fastlane
或sudo gem install fastlane
。 当您使用OS X提供的Ruby版本时,后者是必需的。
项目设置
安装必备组件后,您必须初始化您的项目以使用fastlane。 在项目文件夹中,从命令行运行fastlane init
以启动交互式安装向导。 向导会要求您提供电子邮件地址 ,如果钥匙串中还没有密码,则可能会要求您输入密码 。 该向导还将检测应用程序的属性(例如名称和标识符) ,并检查Developer Portal和iTunes Connect是否已存在。 如果不是,那么它会为您创建它。 无痛。
您也可以在同一步骤中设置投放 。 此工具可让您为您将元数据,屏幕截图和二进制文件上传到iTunes Connect。 我们将在另一个教程中对此进行研究。
在设置过程中,将在项目目录中创建一个新文件夹fastlane 。 它包含配置数据,最重要的是一个名为Fastfile
的文件。 该文件描述了fastlane拥有的车道。 这是默认的应用appstore
通道。
desc "Deploy a new version to the App Store"
lane :appstore do
match(type: "appstore")
snapshot
gym
deliver(force: true)
frameit
end
该工作流或通道执行以下操作:
- 获取所有签名证书和配置文件( 匹配 )
- 为您的应用创建屏幕截图( 快照 )
- 为应用商店( 健身房 )构建应用
- 将屏幕截图,元数据和存档上传到iTunes Connect( 交付 )
- 使用屏幕快照中的设备框架创建营销图像( frameit )
在本教程中,我们将详细介绍第二步,即快照 。
使用快照自动截图
为什么要自动化截图? 它们很容易在模拟器中完成。 当只有一种设备或一种语言时,这可能是正确的。 让我们做数学。 如果您的应用程序可在iPhone和iPad上使用,则您有六种屏幕尺寸(4.7英寸,5.5英寸,4英寸,3.5英寸,iPad和iPad Pro)。 我们还假设您的应用程序支持20种语言,并且您截取了五个屏幕截图。
6(设备)×20(语言)x 5(屏幕截图)= 600截图
现在想象一下,您必须手动进行操作。 太疯狂了 幸运的是,这里有快照 。 它使用Apple提供的自动化工具来自动拍摄屏幕截图。 更好的是,从Xcode 7开始,我们不再需要使用JavaScript来自动执行此操作。 我们可以将Swift和UI测试用于此任务。
安装fastlane时,也会安装快照 。 但是,在设置新项目时,它不会自动使用它初始化快照 。 您需要在项目文件夹中运行snapshot init
。
这将在fastlane文件夹中创建两个文件Snapfile
和SnapshotHelper.swift
。 您必须将Swift文件添加到项目的UI测试目标中。
添加此文件后,您还需要使用提供的代码段快照来保存屏幕截图。 您可以使用Xcode生成的UI测试文件,也可以只为截图创建一个单独的UI测试文件。
在setUp()
函数中,将XCUIApplication().launch()
替换为以下代码:
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
为了清楚起见,您还可以重命名testExample()
,但请确保不要删除函数名称的test
前缀。
现在是时候记录您生成每个屏幕截图的步骤了。 您还可以通过编程方式控制应用程序,但是使用Xcode的录制功能并在以后进行编辑以满足您的需求要容易得多。
当您记录一个简单的交互时,您最终得到的代码看起来类似于以下内容:
func testScreenshots() {
let app = XCUIApplication()
let masterNavigationBar = app.navigationBars["Master"]
let addButton = masterNavigationBar.buttons["Add"]
addButton.tap()
addButton.tap()
let tablesQuery = app.tables
tablesQuery.staticTexts["2016-04-12 08:43:40 +0000"].tap()
app.navigationBars.matchingIdentifier("Detail").buttons["Master"].tap()
masterNavigationBar.buttons["Edit"].tap()
tablesQuery.buttons["Delete 2016-04-12 08:43:39 +0000"].tap()
tablesQuery.buttons["Delete"].tap()
masterNavigationBar.buttons["Done"].tap()
}
该示例来自Xcode提供的默认的Master-Detail Application模板。 立即,您可以看到此代码的问题。 它使用特定的标识符与应用程序进行交互。 如果我们再次运行UI测试,则由于时间戳不同,它将失败。
第一步,我们可以使用UI测试框架提供的函数elementBoundByIndex(_:)
。 这使我们可以使用索引访问元素,例如按钮和表格视图单元格。 这将导致以下代码:
func testScreenshots() {
let app = XCUIApplication()
let masterNavigationBar = app.navigationBars["Master"]
let addButton = masterNavigationBar.buttons["Add"]
addButton.tap()
addButton.tap()
let tablesQuery = app.tables
tablesQuery.cells.elementBoundByIndex(0).tap()
app.navigationBars.matchingIdentifier("Detail").buttons["Master"].tap()
masterNavigationBar.buttons["Edit"].tap()
tablesQuery.cells.elementBoundByIndex(0).buttons.elementBoundByIndex(0).tap()
tablesQuery.buttons["Delete"].tap()
masterNavigationBar.buttons["Done"].tap()
}
当我们尝试以多种语言运行代码时,我们还有另一个问题。 由于Master , Add等在每种语言中的命名不同,因此失败。 我们也可以通过使用elementBoundByIndex(_:)
方法来解决此问题。 请注意,导航栏上的右栏按钮实际上具有2的索引,这意味着它是第三个元素,因为导航栏始终具有隐藏的后退按钮。
func testScreenshots() {
let app = XCUIApplication()
let masterNavigationBar = app.navigationBars.elementBoundByIndex(0)
let addButton = masterNavigationBar.buttons.elementBoundByIndex(2)
addButton.tap()
addButton.tap()
let tablesQuery = app.tables
tablesQuery.cells.elementBoundByIndex(0).tap()
app.navigationBars.elementBoundByIndex(0).buttons.elementBoundByIndex(0).tap()
masterNavigationBar.buttons.elementBoundByIndex(0).tap()
let cell = tablesQuery.cells.elementBoundByIndex(0)
cell.buttons.elementBoundByIndex(0).tap()
cell.buttons.elementBoundByIndex(1).tap()
masterNavigationBar.buttons.elementBoundByIndex(0).tap()
}
还有另一个快捷方式,可以使UI测试更轻松地访问自定义元素。 它是一个属性accessibilityIdentifier
,由UIAccessibilityIdentification
协议定义。 您可以使用它来查找具有此标识符的元素,例如app.buttons.matchingIdentifier("awesomeButton").element
。 即使用户启用了辅助功能,辅助功能标识符也不对用户可见,并且也未本地化。
设置好用户界面以使用项目支持的语言后,是时候配置快照以截取一些屏幕截图了。 这是通过UI测试中的snapshot(_:)
函数完成的。 您还需要指定一个文件名。 我个人使用带编号的前缀,例如snapshot("1MasterView")
或snapshot("2DetailView")
,以便更轻松地计算已经拍摄的屏幕截图数量并自动对其进行排序。 如果在截屏之前需要更多时间,请使用sleep(_:)
函数。
最后,您需要告诉快照它应使用哪些设备和语言。 这在Snapfile
指定。
devices(["iPhone 6", "iPhone 6 Plus", "iPhone 4s"])
languages(["en-US", "de-DE"])
在此示例中,我使用iPhone 6,iPhone 6 Plus和iPad作为设备,并使用英语和德语作为语言。
要运行该工具,您可以从命令行执行snapshot
。 根据项目的大小以及设备和语言的数量,截屏可能要花费一些时间。 同时,您可以伸展双腿,喝杯咖啡,或者只是看着它发挥作用。
默认情况下,屏幕快照存储在fastlane / screenshots中 ,每种语言都有其自己的子文件夹,并且文件名带有设备名称前缀。 快照完成后,它还会生成一个HTML文件,以轻松预览生成的屏幕截图。
结论
通过使用快照 ,您可以将为应用程序创建屏幕截图所需的时间和精力减少到手动执行此任务所需的时间的一小部分。 当然,该工具的可定制性更高,因为我们仅涉及快照可以完成的工作。 有关更多信息,请查看GitHub上的文档 。 如果您想了解更多有关此出色工具的信息,还可以查看我的有关fastlane的视频课程 。
翻译自: https://code.tutsplus.com/tutorials/how-to-automate-screenshots-with-fastlane--cms-26151