GramFrame for iPad
– 07 April 2011– 1113 words
GramFrame for iPad is available on the App Store. Go get it now!
This is the story of GramFrame, an app that turns your iPad into a beautiful ambient display using images from Instagram.
Back on March 16, I created a very simple app in a couple of hours and wrote a small post to see if anyone would want it. Turns out a few people did, so I built it.
You see, I'm an API junkie. When a new API comes out, I just have to play with it. So when Instagram came out with their API, I had a look around and thought about fun things to build.
The first thing was Pic A Fight, which I built with my co-founder, Paul. He wrote about the making of the site, if you are interested.
I had always admired the Mac screensaver with slowly falling and rotating pictures. I set mine to Cosmos because space is awesome.
In the screensaver, images start out with zero opacity and a large frame (as if the images are high above the screen), and gradually fade in and fall onto the desktop with a little extra spin as it hits for that extra special attention to detail.
I wondered if I could recreate that effect on an iPad. I was learning some things about Core Animation, and it seemed simple enough. With the new animation block syntax I had a working prototype in very few lines of code.
Then I decided to use Instagram as the image source. This would provide an ever-updating supply of beautiful images (taken from the popular feed). Using the amazing ASIHTTPRequest and SDWebImage libraries, I was able to put together enough of an app to take a crude video and post it on this blog to let people have a look.
I got some positive feedback, but people wanted to be able to see their friends' photos or their own photos. Fair enough. I added those features in and started testing.
Each image was bordered by an outline of a Polaroid picture for visual effect, and the username of each picture was written on the bottom to make it look like they signed each photo. These signatures were randomly rotated +/- 2 degrees to give it a more human, non-perfect look.
I pinged the guys at Instagram to see if they wanted to help test. Mike, Kevin, and Shayne got back to me quickly saying yes, and using the awesome TestFlight service I was able to send them updates regularly.
Kevin posted a picture to Instagram of Mike showing off one of the beta builds, and it got a bunch of likes and comments to the effect of, "Wow, I want that app now! Where can I get it?" That felt pretty good.
On March 18th I submitted the final build to Apple.
When you submit a new app, you can choose when the app will go on sale. I picked March 31st thinking that would be far enough in the future that I could figure out how best to promote it after it was approved and then release the app at my leisure.
Ten days later, on March 28, I got a rejection email. Apparently they had balked at my use of a Polaroid image in the app.
They said that Polaroid had complained before about infringement of copyright when people included likenesses of Polaroid images in their apps, and I must show proof of written consent from Polaroid before I would be approved. Well, of course I had no such proof, so I decided to rip out all the Polaroid references and just use a thin white outline to border all of the pictures. I moved the users' "signatures" up into the bottom left corner of the picture, but this time I put it on top of a small white rectangle with 0.6 opacity which made it appear like masking tape. I left in the random rotation because the effect was so cool.
I'm not sure how Instagram deals with this Polaroid issue themselves; maybe they have some sort of licensing agreement?
I resubmitted the app that afternoon.
On April 1st I was notified that the app was approved! I had forgotten that it was now past the March 31st date I had previously set, and woke up to find that the app was already live on the App Store. Oops. There was still one piece to this puzzle that was missing.
When using the Instagram API, you can either request methods with your app's client_id token, or with a user's access_token once they have granted access to your app. You get 5000 requests/hour or so with each kind of token. Since I was using my client_id token to request the popular photos for people that were not logged in, this was a problem. If too many people had the app open at once, it would deplete the rate limit and cause all sorts of grief.
Instagram will raise the rate-limit for an app if you ask for their permission, so I did. The response I got was, "[We'd] suggest caching the response from our server. When users that are not logged in request popular, they'll hit your cache, instead of making a request to the Instagram server, every time. This will help keep you under our limits."
That makes perfect sense, of course, but it would also mean I would have to have a server setup somewhere to send the cached response out to the app for logged-out users. This was not overhead I was willing to incur. So, I decided ultimately to just store a static json file in the app with a long list of popular photos that the app uses for logged-out users. That way no API calls are made at all until you login with your Instagram account. It's sort of a dirty hack, but it solved both problems at once.
I also added a "Share" button in the bottom toolbar that will let people send out links for the app on Email, Twitter, and Facebook. I resubmitted the app on April 4th, and a short two days later, it was approved again.
All in all, I think it turned out pretty well. I've set the price at $1.99 - half the cost of a latte, so no complaining! It's a fascinating way to watch your friends' photos on your iPad, and I hope you enjoy watching it as much as I enjoyed making it.
Go get GramFrame on the App Store now!
You made it to the end. Congrats! Have a promo code:
64N96FFAPL3X
LRXK4M9EF3NN
3M4MW6ME6KYT
6W9H6RE7HM4N
APTJ4WHPH7KX
3YKK64RLP4K9
T6RTLXR7YHTW
EJFL77HLYHA6
FFT43X7XKJ6N
Y79YMR7KWM7L
— Fin.