faslane iOS 及 tvOS屏幕截图功能
屏幕截图对于驱动你的那些潜力用户下载或者后买你的app具有非常大的影响力.然而,许多app没有很好地屏幕截图.这经常是由于为你的app提供屏幕截图非常花时间并且非常容易出问题.举例说明:
- 在App Store中你的屏幕截图体现了你的最新页面吗?
- 你的App进行了许多语言本地化并为它们每一个提供不同的截图吗?
- 你能保证没有等待框提示吗?
- 你提供的屏幕截图的尺寸正确吗?
fastlane可以自动化检查流程,并且迅速准确的给你一个漂亮的结果!
选择
你可以查看这篇文章获知其他开发者如何捕捉漂亮的截图.
手动捕捉截图
手动截图花费时间较多,并且降低了屏幕截图的质量.由于它是不是自动化的,截图会因为不同语言和设备的原因而有轻微的不同.许多公司选择为所有国家的使用同一个国家屏幕截图.对于开发者来说这能接受.但对于普通用户来说如果不进行本地化他们将不能读懂屏幕截图中的文字.你是否在屏幕截图中看到你不明白的文字?他很难说服你去下载这个app.
然后,最大的不足是你将不停的重复这个流程.如果你不小心在截图时犯了一个错误并将它更新到了新的发布版本上,你不得不为所有国家和设备重新创建截图...手动的.
这种方法的积极一面是,您的截图将是清晰的,大小正确,具有可读性的文本.
在App Store中缩放过的截图
app store connect允许您为每种设备类型使用同一组屏幕截图,当在用户设备上的app store中查看时,这些截图将缩放到适当的大小.
虽然这很方便,但是问题是这将会产生尺寸问题:截图和用户在设备上看到的不一致.这可以是个有效的开始方式,因为你可以在后续版本中为特定语言和设备重新截图.
自动捕捉截图
在你的app中使用fastlane的自动截图功能,你可以:
- 在所有模拟器中为多种语言截取多张屏幕截图
- 短时间内即可在不同的设备模拟器上截图
- 在截图时你可以干点别的
- 设置一次并保存团队中其他人也可以执行
- 生成一个包含所有显示所有设备的屏幕截图网页.这是最好的给测试,市场或者翻译验证的方式.
- 防止在截图时出现等待网络请求的载入框
- 为你的app如何在不同设备及语言上展示提供一个总结
以使用UI测试为开始
屏幕截图使用了苹果的UI Tests工具.你可以参考一下文章来熟悉UI Tests:
- WWDC 2015 Introduction to UI Tests
- A first look into UI Tests
- UI Testing in Xcode 7
- HSTestingBackchannel : ‘Cheat’ by communicating directly with your app
- Automating App Store screenshots using fastlane snapshot and frameit
开始UI test,你可以打开UI test recorder,方法是点击窗口底部的红色记录按钮.通过记录你操作模拟器的记录,Xcode会为你生成UI Test代码.你可以参考这篇文章.
设置快照
为你的app创建一个UI Test target(根据上文).
在你的项目目录下执行
fastlane snapshot init
.在UI Test target下添加
./SnapshotHelper.swift
文件(你可以在任何时候移除这个文件)为新创建的UI Test target添加新的Xcode scheme
编辑scheme
In the list on the left click "Build", and enable the checkbox under the "Run" column for your target.
为新建的scheme选中Shared选择框
-
(OC情况)为你的test class添加桥接文件
- #import "MYUITests-Swift.h"
- 桥接文件名为你的target名字加上'-Swift'.
在UI Test class,点击记录按钮开始记录
-
使用如下代码进行快照
- Swift: snapshot("01LoginScreen")
- Objective C: [Snapshot snapshot:@"01LoginScreen" timeWaitingForIdle:10];
添加如下代码到你的
setup()
方法:
Swift:
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
OC
XCUIApplication *app = [[XCUIApplication alloc] init];
[Snapshot setupSnapshot:app];
[app launch];
- 在终端中执行
fastlane snapshot
.
警告:在Xcode中执行测试不会得到正确的snapshot-虽然测试不会失败.需要命令行创建了必须的子目录,重命名用以迭代概览网页.
这些设置也会生成一个Snapfile
,和这个类似:
# A list of devices you want to take the screenshots from
# devices([
# "iPhone 6",
# "iPhone 6 Plus",
# "iPhone 5",
# "iPhone 4s",
# "iPad Retina",
# "iPad Pro"
# ])
languages([
"en-US",
"de-DE"
])
# The name of the scheme which contains the UI Tests
# scheme "SchemeName"
# Where should the resulting screenshots be stored?
# output_directory "./screenshots"
# clear_previous_screenshots true # remove the '#' to clear all previously generated screenshots before creating new ones
# Choose which project/workspace to use
# project "./Project.xcodeproj"
# workspace "./Project.xcworkspace"
# For more information about all available options run
# fastlane action snapshot
你也可以为你的项目修改这个文件的配置.每当你运行fastlane snapshot
文件将会被自动载入.
如果需要列出在Snapfile
中所有可用的配置参数可以执行fastlane action snapshot
.
如果你已经安装了fastlane,尝试一个snapshot将会非常容易,首先clone fastlane repo,进入对应文件夹,执行fastlane snapshot
git clone https://github.com/fastlane/fastlane # Clone the fastlane repo
cd fastlane/snapshot/example # Navigate to the example project
fastlane snapshot # Generate screenshots for the sample app
上传屏幕截图到App Store
通常当你使用fastlane snapshot获得截图后,你会将它上传到App Store Connect.
如果你遵循刚刚的设置向导,已经安装了执行了fastlane init
,在你的目录fastlane/screenshots and fastlane/metadata
下应该已经存在屏幕截图及元数据.默认设置下执行fastlane snapshot
将会保存屏幕截图到fastlane/screenshots
.
上传保存好的截图,只需执行
fastlane deliver
在你真正上传截图之前也会生成一个新元数据总结,它也包含这当前App Store Connect中的元数据及截图.
在fastlane中使用
为了是你团队中任何人都可以更新并上传新的截图,你可以在fastlane中定义screenshots
任务,它可以:
- 运行你的app并自动捕捉snapshot
- 发送最终的屏幕截图到App Store
添加下面的代码到你的fastlane/Fastfile
:
lane :screenshots do
capture_screenshots
upload_to_app_store
end
执行以下命令获取所有可用的选项:
fastlane action capture_screenshots
fastlane action upload_to_app_store
使你的截图添加设备外形
frameit帮助你只需使用简单的代码即可使你的截图添加设备外形.他提供:
- 多设备适配
- 竖屏横屏适配
- 黑白设备适配
- 设置背景颜色以及富文本
使用方式
需要在当前目录自动添加包含设备的屏幕截图只需执行:
fastlane frameit
他只会为你的屏幕截图添加设备外形,不会添加背景及标题.这些图片可用于你的网页,邮箱等等.
如果你想自定义标题及背景,你可以设置Framefile.json
更多的信息你可以点击https://docs.fastlane.tools/actions/frameit/#titles-and-background-optional
如果你想上传截图到App Store,你必须提供Framefile.json
标题及背景,不然该截图不符合App Store Connect规范.
依赖
安装ImageMagick
frameit依赖imagemagick
管理图片库.最简单的安装方式是通过homebrew:
brew install libpng jpeg imagemagick
安装ImageMagick失败
如果你在安装ImageMagick时候遇到了如下的错误信息:
mogrify: no decode delegate for this image format
PNG'
`
你需要更换源并重新安装:
brew uninstall imagemagick; brew install libpng jpeg; brew install imagemagick --build-from-source
设置屏幕尺寸
为你的开发项目添加尺寸,添加下面的代码到你的Fastfile:
lane :screenshots do
capture_screenshots
frame_screenshots(white: true)
upload_to_app_store
end
为了获取更多frame_screenshots
的可用参数:
fastlane action frame_screenshots
进一步了解snapshot
简单应用
lane :screenshots do
capture_screenshots
end
默认的,你的screenshots会存储在./screenshots
中.
如果你在设备上运行snapshot脚本时发生了错误,设备将不会有任何screenshots,snapshot会再下一台设备或语言上运行.如果你想在发生错误时终止脚本,执行:
capture_screenshots(stop_after_first_error: true)
在默认情况下,snapshot在完成任务后打开一个HTML.这可以被下面的命令省略
capture_screenshots(skip_open_summary: true)
已经有许多可选配置定义如何构建你的app:
capture_screenshots(scheme: "UITests", configuration: "Release", sdk: "iphonesimulator")
你可以在执行snapshot前从新定义它们:
capture_screenshots(reinstall_app: true, app_identifier: "tools.fastlane.app")
当snapshot失败时它默认会从新尝试UI Tests.重试次数是随机的.你也可以设定重试次数:
capture_screenshots(number_of_retries: 3)
如果需要在截图前添加图片或者视频你可以执行:
capture_screenshots(add_photos: "MyTestApp/demo.jpg", add_videos: "MyTestApp/demo.mp4")
查看所有可选参数
fastlane action capture_screenshots
重置Xcode模拟器
你可以使用下面的命令删除并重新创建所有的iOS模拟器.当你的本地设备被Xcode复制时这将很有用.
fastlane snapshot reset_simulators
启动参数
你可以在程序启动时提供额外参数.这些参数在你的app中可用(但是在testing target中不可用)通过NSProcessInfo.processInfo().arguments
.或者使用存储在userDefault中的key-value形式的值.
launch_arguments([
"-firstName Felix -lastName Krause"
])
name.text = NSUserDefaults.standardUserDefaults().stringForKey("firstName")
// name.text = "Felix"
snapshot包含-FASTLANE_SNAPSHOT YES
,这会在FASTLANE_SNAPSHOT
这个key下设置一个临时用户.你可以用这个来检测snapshot是否运行
if NSUserDefaults.standardUserDefaults().boolForKey("FASTLANE_SNAPSHOT") {
// runtime check that we are in snapshot mode
}
为不同设备,语言或者其他参数你可以为snapshot设置不同的参数.这在为不同国家/语言设置不同snapshot的时候非常有用
# Snapfile for A/B Test Comparison
launch_arguments([
"-secretFeatureEnabled YES",
"-secretFeatureEnabled NO"
])
更新snapshot helpers
有时候snapshot需要更新文件.他会自动警告你它需要更新了
你可以执行
fastlane snapshot update
用来更新你的SnapshotHelper.swift
文件.如果你更改了SnapshotHelper.swift
,并且向手动更新,可以查看SnapshotHelper.swift.
除去状态栏
为了清除状态栏(类似电池或者信号),使用SnapshotHelper.swift
snapshot的工作原理
最简单的方式是截取UIWindow到一个文件中.但是因为UI Tests不在main线程中执行所以不能这样做.所以snapshot使用了另一种方式.
当你在Xcode中执行你的unit tests时.它生成一个plist文件,记录了你在测试时候所有的事件.另外,Xode在生成snapshot前/后也会记录事件.有很多方式去记录screenshots事件.这些截图和事件会存储在DerivedData目录下,snapshot会存储在一个临时文件夹下.
当你在UI test中调用snapshot(...)
时,脚本会转换成.Unknown
这样就不会对真正的App造成影响,但足够生成screenshots.你不需要在你的test中做额外的事情.我们通过找到那些不是用户触发的事件既可以知道这些是屏幕截图事件.
然后快照迭代所有测试事件,并检查我们在哪里进行了这种奇怪的旋转(在iOS上)或搜索浏览器(在tvos上).一旦快照具有由快照触发的所有事件,它将收集应用程序实际屏幕截图的所有文件名的有序列表.
在测试的输出中,snapshot会想下面这样打印:
snapshot: [some random text here]
snapshot使用regex查找所有这些条目。终端中的快照输出数和plist文件中的快照事件数应该相同。知道了这一点,快照会自动匹配这两个列表,以标识每个截图的名称。然后将它们复制到输出目录,并由语言和设备分隔。
两个参数会用过snapshot发送到xcodebuild命令行工具上:
- 设备型号通过
destination
作为参数传给xcodebuild命令行工具 - 语言通过一个临时文件传递,该文件在运行测试之前由快照写入,在启动应用程序时由UI测试读取.
如果你知道更好的办法获得snapshot.你可以提交PR告诉我们.
fastlane iOS官方翻译四 (生成测试包)