Save yourself from spending hours on screenshots for the App Store. Here's a step-by-step guide on how you automate the process of taking screenshots for all supported screen sizes and languages.
Automate Screenshots for App Store Using Fastlane
Written by
In my last post, I shared with you the source code for an app called QCards that I released on the App Store. The screenshots that went on the App Store were all generated using Fastlane. In this post, we'll go over how I went about generating them.
Here's why you shouldn't create screenshots for the App Store manually. Imagine your want four different screenshots to preview you app. But you also support four different languages. And not to mention, you support both iPhone and iPad which is three screen sizes in total (iPhone 5.5", 6.5" and iPad Pro).
4 previews x 4 languages x 3 screen sizes = 48 screenshots 😱
And get ready to repeat the process each time you change the layout of the app. So let's instead automate this.
Initializing Fastlane
The first thing you need to do is to install Fastlane if you haven't already. Open your terminal and run this command: sudo gem install fastlane -NV
.
Next up, navigate to the directory of your project. From here, you want to run fastlane snapshot init
which will create two files, Snapfile and SnapshotHelper.swift, for you.
Create a new folder in the root of your project folder. Call it "fastlane" and move Snapfile into the folder.
UI Test Target
What you want to do now is to add a UI Testing Bundle target to your project.
Give the target a name. You could call it "FastlaneSnapshot".
Now, you need to move the SnapshotHelper.swift file to this newly created target. Make sure to update the target membership of this file to FastlaneSnapshot.
UI Test Scheme
Add a new scheme called "FastlaneSnapshot". Make sure to select the UI Test target here.
Once you've done that, go to Edit Scheme -> Build
. Make sure to give it the following settings:
Also, make sure to check off the Shared
option.
Update Snapfile
Open up the Snapfile and update it to your needs, including the scheme to "FastlaneSnapshot". Here's how it could look:
# Uncomment the lines below you want to change by removing the # in the beginning # A list of devices you want to take the screenshots from devices([ "iPhone 11 Pro Max", "iPhone 8 Plus", "iPad Pro (12.9-inch) (3rd generation)" ]) languages([ "en-US" ]) # The name of the scheme which contains the UI Tests scheme("FastlaneSnapshot") # Where should the resulting screenshots be stored? output_directory("./fastlane/screenshots") # remove the '#' to clear all previously generated screenshots before creating new ones clear_previous_screenshots(true) # Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments # launch_arguments(["-favColor red"]) # For more information about all available options run # fastlane action snapshot
Now we are set up and ready to take the actual screenshots of the app.
Take the screenshots
What you need to do is write UI tests that navigate through the screens you want to capture. I won't go over how this works in this post, but it's not too difficult to figure out. Make sure to check out the code from my QCards app here for inspiration.
The entry point for Fastlane is a test function called testGenerateScreenshots
that you need to provide. From here, you can navigate your app as you like. I usually split navigation between my screens up in several functions that I call from testGenerateScreenshots
to keep it slim and readable.
What's provided by the SnapshotHelper.swift file is a function func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20)
. You call this throughout your UI tests, whenever you want to capture a screenshot. It could look something like snapshot("LoginScreen")
.
Here's an example of the snapshot
function in action:
import XCTest let deckTitle = "My presentation" let cardTitle = "First topic" let cardContent = "Here are some very important points" class FastlaneSnapshot: XCTestCase { override func setUp() { super.setUp() continueAfterFailure = false let app = XCUIApplication() setupSnapshot(app) app.launch() } func testGenerateScreenshots() { let app = XCUIApplication() app.navigationBars["QCards"].buttons["createDeckButton"].tap() let deckTitleField = app.textFields["deckTitleTextField"] deckTitleField.tap() deckTitleField.typeText(deckTitle) app.buttons["addButton"].tap() snapshot("AllDecks") createCard() } func createCard() { app.tables.staticTexts[deckTitle].tap() app.navigationBars[deckTitle].buttons["addButton"].tap() let cardTitleTextField = app.textFields["cardTitleTextField"] cardTitleTextField.tap() cardTitleTextField.typeText(cardTitle) let cardContentTextView = app.textViews["cardContentTextView"] cardContentTextView.tap() cardContentTextView.typeText(cardContent) snapshot("CreateCard") } }
Running the tests won't capture the screenshots. What you need to do is to open your terminal, navigate to the fastlane folder inside your project and run fastlane snapshot
. This will create a screenshots folder inside the fastlane folder, containing all of your captured screenshots.
Conclusion
That was it! A great way to automate a tedious task that would otherwise cost you several hours now and each time you change your layout of your app. It doesn't take long to setup and grab the screenshots you need, so there’s no reason to hold back!
In the next post, we'll go over how you automate framing you screenshots, adding a background and localized texts.
If you haven't done so already, check out the source code for the QCards app on GitHub.
Share this post
Facebook
Twitter
LinkedIn
Reddit
You may also like
Automation
Automate Screenshot Framing with Text Using Fastlane
Framing your App Store screenshots greatly improves your store listing. But doing it manually takes hours away from perfecting your app. Instead, here’s how you automate the process of adding device frames and text to your screenshots.
DevOps
Architecting a Logging Service for iOS Apps
Understanding how your apps behave in production is a fundamental part of our jobs as iOS engineers. We need to gather log events in order to investigate and reproduce issues that customers run into. Here’s how you create a log service with a clean architecture that’s modular and easily extensible.
Automation
The Ten Commandments of iOS Development
Here’s a set of key principles to guide you to do iOS development according to best practices. They are all about the bigger picture of iOS development, including processes and architecture decisions – not simply language specific challenges.