Skip to main content

Framing your app store screenshots with device frames using frameit from fastlane


I have already written about how fastlane can make uploading screenshots to iTunesConnect easier and in this post and in this post I will talk about another one of it's very useful tools i.e. frameit. If you look at App Store screenshots for my iOS app My Day To-Do, you will see that they look great with a nice device frame around them, something which I achieved using the frameit gem from fastlane. The documentation on frameit as of now doesn't talk about everything and learning how to use it takes a bit of effort which is fair enough I suppose. I mean they gave us a great tool so it is only fair that we contribute to it somehow so in this post, I will talk about what I learned while using frameit to frame my App Store screenshots. There were some rules I had to follow to successfully use frameit for my iOS app and here I will share what I learned so it saves the next person learning to use it some time. Ohh and in my quest to save the next person some time, I have also created this pull request for the fastlane examples repo

Background

Initially I thought that simply annotating App Store screenshots with some text via speech bubbles using the Mac Preview tool should be enough to attract prospective users attention. I did come across the fastlane frameit tool but I just ignored it and thought "nahh surely it can't make the screenshots look that good!" until a couple of months later when someone told me that framed screenshots result in better downloads. So I decided to have a look at fastlane and when I saw what a framed screenshot, I just thought "WOAH!!! they do look better" have a look at the screenshots to see the difference for yourself
Framed screenshot with a title

Screenshots with annotations only



So looking at it, while my original screenshots with annotations certainly gets the message across the framed screenshot just look a little bit better in comparison, I think.

Must know info on using frameit

The frameit docs do cover everything there is to know about using frameit but there were just a couple of little things that I had to learn by trial and error. Also when I was learning how to use it, I really wished I had a full working sample of a project with the images. The MindNode example has all the necessary files except the actual screenshots and it also doesn't provide any details into some of the rules that you must follow to get frameit working. So without further a due, let's start on it.

p.s. I won't be talking about some of the basics already available in frameit docs or things like where to store your device frames for which frameit does a great job of telling you where to download from and store your device frames.

The setup

Here's a screenshot of the setup for my app



I have a folder titled screenshots in the folder for my app My Day To-Do, in which I have my Framefile.json, background.jpg, followed by my localisation folder. Right now I only my en-US localisation which has the screenshots and my keyword.strings and title.strings. 

The Framefile.json must knows

One of the things that you should know about Framefile.json is that make sure you don't leave any trailing commas or anything in your JSON structure. e.g. the code below will work

"default": {
"title": {
"color": "#545454"
},
"padding": 25
"background": "./background.jpg",
},
but this wont
"default": {
"title": {
"color": "#545454"
},
"padding": 25,
"background": "./background.jpg",
},
You will just get the error that maybe something like this,


Invalid JSON file at path './myDayTodos/screenshots/Framefile.json'. Make sure it's a valid JSON file

I must confess that I am guilty of leaving trailing commas in some of the Javascript code I have written, so I thought I could just leave it here and it will be just fine. 

  {
    "filter": "2_iphone6_2",
    "keyword": {
      "color": "#feb909"
    }
  },
  {
    "filter": "3_iphone6_3",
    "keyword": {
      "color": "#aa4dbc"
    }
  }
Even though the data part of the JSON file is self explanatory, I did not find it so obvious while working with it initially. 

Now the format of the code above is 

filter: imagename

So 1_iphone6_1 is the name of my image file for the screenshot and for the keyword we specify a colour of the keyword found in the keyword.string file. 

Again even in this structure you cannot have a trailing comma e.g. no trailing comma after the filter object for 2_iphone6_2.

Keyword.string and Title.string

Ok so it's best we look this with a sample. 

Have a look at the screenshot on the right, the text in that screenshot comes from the following

keyword.strings

"3_iphone6_3" = "Speech"; 

title.strings

"3_iphone6_3" = "select the language in which\nthe app talks to you";


As noted above 3_iphone6_3 is the name of the image file on disk and if you remember we defined a colour for our keyword in our framefile.json 

So how does this work? have a folder for your localisation, save your screenshots there, use the name of the screenshot and specify both a title and a keyword for that screenshot.



App Store ready screenshots

As the frameit docs will tell you, by default frameit doesn't generate screenshots that you can upload to iTunesConnect. For that you need to generate screenshots that have a title and to add titles you must provide a background before you run the frameit command. 

Finally


Lastly, it should be no surprise that frameit will work as expected when being applied to images inside a fastlane project. 

Wait what am I talking about?

Once I installed frameit on my mac, I realised that I could run the frameit command from anywhere on my mac so, 
  1. I created and setup a directory for my app screenshots on my mac, 
  2. navigated to the directory on the command line 
  3. run the frameit command. 
And guess what? It doesn't quite work as you would expect it to. Have a look at the screenshot on the right that you can see what the end product looks like (it's missing the device frames).

The solution 

well make sure you run the frameit command in a fastlane project e.g. this was the  folder hierarchy  

MyDayToDo (my app directory)
   screenshots (my app screenshots)

So in the MyDayToDo directory I would run fastlane init to make it a fastlane project and then it works as expected. 



Conclusion

Despite the initial learning curve(at least in my case), I reckon it's absolutely worth learning how to use frameit and use it to frame your app screenshots for the App Store. So give it a try and use it to frame your screenshots for your next app update. This is my pull request to add My Day To-Do example to the faslane examples and I hope that it gets merged with the main repo.




Finally, I am working on my app full-time right now so if you find my blog posts useful and want to support me you can 
  1. Either buy the complete version of My Day To-Do
  2. Or one of the limtied (cheaper) versions, LC or W
  3. Or just give the Lite(free) version a try
Any feedback on my apps or the way I write my post, would be great.



Comments

Popular posts from this blog

Upload to AWS S3 from Java API

In this post, you will see code samples for how to upload a file to AWS S3 bucket from a Java Spring Boot app. The code you will see here is from one of my open-source repositories on Github, called document-sharing. Problem Let’s say you are building a document sharing app where you allow your users to upload the file to a public cloud solution. Now, let’s say you are building the API for your app with Spring Boot and you are using AWS S3 as your public cloud solution. How would you do that? This blog post contains the code that can help you achieve that. Read more below,  Upload to AWS S3 bucket from Java Spring Boot app - My Day To-Do (mydaytodo.com)

Addressing app review rejections for auto-renewing subscription in-app purchase (iOS)

The ability to know what the weather is like while planning your day is a feature of  My Day To-Do  Pro and as of the last update it’s also a part of the  Lite version . Unlike the Pro version it’s an auto-renewing subscription based  in-app purchase (IAP)  in the Lite version. What means is that when a user purchases it, the user only pays for the subscription duration after which the user will be automatically charged for the next period. Adding an  auto-renewing  subscription based IAP proved to be somewhat challenging in terms of the app store review i.e. the app update was rejected by the App Review team thrice because of missing information about the IAP. Therefore in this post I will share my experiences and knowledge of adding auto-renewing IAP in hopes to save someone else the time that I had to spend on this problem. In-App purchase This year I started adding IAPs to My Day To-Do Lite which lead to learning about different types of IAP...

Serving HTML content in an iOS app that works in iOS 7 and later (using Swift)

As I have mentioned in an earlier post , I really enjoying coding in Swift. Now what am I doing with it? Well I am trying to build an HTML5 app that must work on devices with iOS 7. So in iOS8 apple has introduced a whole bunch of features that facilitate easy communication between web content and lets just call it back-end Swift code, but those features are not in iOS 7. So why do I want to build something that would work in an older OS? well I do not expect existing iOS users to upgrade to iOS 8 straight away and i also know a couple of people who would be very reluctant to upgrade their iPhones to iOS 8. Now in case you do not, you can have a read of the "Working with WebViews" section of this post , to know how to serve HTML content with WebViews. So when I started building my app, I wanted to know: How do I invoke some Swift code from my HTML content? Well the solution to this may feel a little bit "hacky" but it is a solution to achieve this.  The followi...