Originally published in my 100 days of code log
I had seen several apps in the app store with cool screenshots with frames and titles, and I really wanted to do that. It seemed like a huge PITA given how long it takes to go through the simulator and take screenshots in the first place. When I saw a post about beautiful automated screenshots, I wanted to jump right in. Granted, the post was old, but the ideas were exactly what I needed, and it seems the tools are about the same, probably better.
Why fastlane?
Fastlane includes tools to help you automate the process of generating and cleaning up screenshots in multiple languages and for all platforms that your app targets. Not only that, but it also automates the process of managing build numbers, provisioning, and uploading your app for beta testing and release. Magic, no?
I'm assuming that if you are reading this, you might be a lot like me, yesterday morning. You have an iOS app and some experience with iTunes Connect. You've uploaded before, at least some app, because the fastlane value comes from saving time in these steps that you know take FOREVER once you've done them a few times. I'll further assume that you are comfortable with the terminal shell and git ...and you also need to not freak out about installing a bunch of stuff. You should set up fastlane if you ever plan to make changes to your app, ever make another app, or have several languages for your app. Let's take a moment to be jealous of our future selves with all that time saved. Ahhh.
Okay, I'm ready, how?
The documentation is very useful, but it was not always accessible to me when I was trying to get things to work for the first time. You can certainly do like I did and open every single page of the fastlane webiste in a tab on your browser and try to lookup all of the things flying by you on the terminal window, or, you could relax a little and follow along here. First, go ahead and navigate your browser to the Fastlane docs for reference.
Basic setup steps
- Fire up the terminal
- If you plan to use fastlane for beta builds or uploads, make sure you enable automatic version control Apple instructions in your Xcode project first
- Install fastlane - I used homebrew
brew cask install fastlane
- Navigate to your project directory - this is the outer one that includes your
.xcworkspace
file. - Initialize your project
fastlane init
(at this point, if you don't have ruby, I think you will need to do some more installations) - Try to read through all the stuff flying by you on the terminal, but don't sweat it. Fastlane is verbose and helpful.
- When the terminal asks you a question, answer as makes the most sense for your project. You can always fix it later if you make a mistake here.
- When everything stops, you should have a fastlane folder.
- Navigate to that folder and open in your favorite text editor
atom .
- Create a ./Gemfile in the root directory of your project with
source "https://rubygems.org" gem "fastlane"
At this point, you have the option to do many things, but I think the best first step is to make sure that your files make sense. Fastlane accidentally assumed that my app bundle id was the first pod in my pods folder, which I had to correct. Let's go through the files that you (with a simple app) need to check and update. Your app may require different settings or other adjustments that I don't show here, please make sure that your settings match what you are doing, especially for export compliance and ratings. If you are missing a file, just create it. There are a couple of places where I say YOUR_UITEST_SCHEME
- if you don't know what that is...we will cover it, just leave that placeholder until you have one.
-- /fastlane/Appfile -- basic information about your app and your itunes connect status
app_identifier "com.TEAM.YOURAPP" # The bundle identifier of your app
# You can find it in your xcode project if you are not sure
apple_id "" # Your Apple email address
itc_team_id "" # iTunes Connect Team ID
team_id "" # Developer Portal Team ID
-- /fastlane/Fastfile -- sets up all the cool stuff you are going to do let's keep it safe for now, no release
You can see here that we have two "lanes": beta and screenshots. More on that later.
default_platform(:ios)
lane :beta do
ensure_git_status_clean
increment_build_number
commit_version_bump
add_git_tag
build_app(
workspace: "YOUR.xcworkspace",
scheme: "YOURMAIN",
clean: true
)
upload_to_testflight(
app_identifier: "YOUR_BUNDLE_ID"
)
end
lane :screenshots do
capture_screenshots(workspace: "YOUR.xcworkspace", scheme: "YOUR_UITEST_SCHEME")
frame_screenshots(white: true)
end
end
-- /fastlane/Deliverfile -- this one makes setup of your iTunes connect a little easier
# The Deliverfile allows you to store various iTunes Connect metadata
# For more information, check out the docs
# https://docs.fastlane.tools/actions/deliver/
price_tier 0
app_review_information(
first_name: "YOUR",
last_name: "YOUR",
phone_number: "YOUR",
email_address: "YOUR",
demo_user: "N/A", # add the user if testers will need to log in
demo_password: "N/A", # add the password if testers need it
notes: "ANY NOTES FOR TESTING"
)
# if you app has more complex structure, check out /fastlane/metadata/review_information folder
submission_information({
export_compliance_encryption_updated: false,
export_compliance_uses_encryption: false,
content_rights_contains_third_party_content: false,
add_id_info_uses_idfa: false
})
automatic_release false
app_icon './fastlane/metadata/AppIcon.png'
app_rating_config_path "./fastlane/metadata/itunes_rating_config.json"
-- /fastlane/Snapfile -- this one handles screenshots you don't need to customize much
# The app bundle
app_identifier "com.TEAM.YOURS"
# A list of devices you want to take the screenshots from
devices([
"iPhone 6",
"iPhone 8 Plus",
"iPhone X"
])
languages([
"en-US",
"de-DE"
])
scheme "YOUR_UITEST_SCHEME"
output_directory "./screenshots"
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
-- /fastlane/metadata/itunes_rating_config.json -- this one may not be in your metadata but go ahead and build it and set it to match your app
{
"CARTOON_FANTASY_VIOLENCE": 0,
"REALISTIC_VIOLENCE": 0,
"PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
"PROFANITY_CRUDE_HUMOR": 0,
"MATURE_SUGGESTIVE": 0,
"HORROR": 0,
"MEDICAL_TREATMENT_INFO": 0,
"ALCOHOL_TOBACCO_DRUGS": 0,
"GAMBLING": 0,
"SEXUAL_CONTENT_NUDITY": 0,
"GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
"UNRESTRICTED_WEB_ACCESS": 0,
"GAMBLING_CONTESTS": 0
}
-- /fastlane/metadata/AppIcon.png -- just go and copy the 1024x version of your appicon and paste it here. If you call it something else, update the path in the Deliverfile
Setup UI Tests for screenshots
At this point, your fastlane folder and files are all setup to allow you to automate screenshots. If you want to add fancy titles to them, you must add any image file that you refer to as the background in the Framefile. I'm not going to cover titles because it is laid out better by frameit and the github example than I could do here. However, I had to learn for myself that the background image could be whatever you wanted. I just created it in GIMP. Play with it. Also, you don't have to have the font statements if you don't want to use a special font.
Fastlane automates your screenshots by taking snapshots during UI testing. Sadly, before I wanted to do this, I had never setup UI Tests because I thought the were super complicated. If you've done them before, just hang with me here. You need to have a UITesting scheme set up to make this work, but we will walk through it, it's not that hard:
- Open your project in Xcode
- Select File/New/Target/..find Cocoa Touch UI Testing Bundle
- Find your new Project_UI_Tests folder
- Click to open Project_UI_Tests.swift
- Paste this inside the function setup, between the {}
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
- Put your cursor in the function testExample, between the {}
- Now, click the little red button at the bottom, a simulator will pop up, and you can navigate through your app - do all of the important things (or not, it can even be just the onboard if you want to get the hang of this)
- When you are finished, click the red button again
- Now, you need to go through what the simulator automated to make sure it is correct. There may be points where the simulator doesn't get out of a text field or doesn't select a choice in a picker.
- When it is fine, pick a few points where you want to have a screenshot and add code like
snapshot("0Login")
orsnapshot("2ChangeDate")
- the idea is to have them ordered chronologically (for your sanity) and with a key that you can use in your Framefile, if you decide to make fancy frames later. - Now, create a new scheme for your tests:
- Scheme - new scheme
- Select your UITests
- Name it something <- this something is what goes in those YOUR_UITEST_SCHEME placeholders above.
- Edit it to ensure that it is shared (there's a little checkbox)
Let's run
So now, we've setup the project to use fastlane, and we've created UI tests to take screenshots. We are all set. Let's try a set of screenshots first. NOTE: Xcode is super testy, and this may take a few tries, also, you may need to edit your UITest function again until all the right inputs happen. We'll assume it works because eventually it will.
Try the Screenshots first
- Save your project work (you actually don't need xcode open now)
- Navigate back to the terminal
- Commit all of your changes
- type
bundle exec fastlane screenshots
-- this will run the "lane" for screenshots that we set up earlier in our Fastfile. - Terminal will be working for a bit. You can try to watch the output fly by or go do something else. Essentially, it is going to go into your project, run the UITests, and take screenshots. It will then combine them all in a nice HTML file.
- Use your screenshots wherever. ...maybe go checkout frameit to make them prettier and good for iTunes Connect
Now the Beta test
- Navigate back to the terminal
- Commit all of your changes <- this is actually important here because our beta lane will scream at us if we have a dirty directory
- type
bundle exec fastlane beta
- Terminal will be working for awhile (took mine 24 minutes). Go do something else. Squats, anyone?
- Celebrate when Testflight notifies you of your new app to test.
That's it. Now, you have a better understanding and can probably use the docs to do even more cool stuff.
Your story was great and all, but I need a different resource
That's cool. I understand. After I did all of my setup and had it working on my machine, I looked for other resources. There is a fantastic tutorial on using fastlane on RayWenderlich. It is slightly outdated, but the approach is sound and they even give you a fake app to play with if you don't want to use yours. Or, maybe you are way ahead of the game and don't have an app yet. Awesome for you.
If the tutorial doesn't help you, try the docs again or reach out to the community here, on github, on stack overflow, or even on twitter.
Top comments (5)
Very good article, gonna stash it for my next project :D
Sadly I had to switch back to "regular" Xcode builds today.
Somehow I couldn't get HealthKit capability working with fastlane/match.
I haven't used HealthKit, but I was facing a little difficulty when fastlane kept originally thinking my project was my first pod. Fixing the Appfile made mine magically work. I wish you good luck in future!!
@maestromac definitely sending you to this post if we ever get into native-mobile world.
This is awesome @jessachandler ! ππΌπ Fastlane has saved me so much time and energy and once you set it up you can let CI do it's job and never have to think about it.
I also have mine setup to handle .env to keep keys and sensitive data out of the repo and it works like a charm.
For instance using Match to load certificates:
Thanks for the props. I :greenheart: Fastlane :rocket: !