Why fit in when you were born to stand out?

Our user Marianne wrote to me a message with the above title, and she kindly explained what it meant.

This saying is from Dr. Seuss, a very famous children’s author.  While he writes for children, his message is universally meaningful to all people.

This quote means;  why be ordinary when you can be spectacular; why follow the crowd when you can be a leader; you were put on this earth to be the best, don’t settle for anything less.

It basically means do your very best in life, because you should, and because YOU CAN.

The saying above made me think of so many thoughts, it also reminded me of some of my past experiences. Before I founded Pinssible Labs, I was a manager at a world leading security software company. The salary was high and the manager was totally great, it sounds like too perfect to be true and that it was comfortable for me to stay there, but something was missing, what I always hoped for, what my heart always wanted was to lead my own team, create things that I am interested in. I always wished for that as I hope my kids can be proud of me when they grow older. I can proudly tell them “Hey honey, this was created by me, oh yeah your dad, it’s cool isn’t it?”.

That’s why I got inspired and founded Pinssible Labs and created Padgram.

When it comes to Padgram, we weren’t the first Instagram iPad app. Our competitor had released its app 8 months before we started coding. we started asking ourselves questions such as: How do we compete with them if we offer another option? how can we be different? how can we be born to stand out? To find out the answers of the above questions, we had to try all the Instagram apps out there, and we found some flaws in them such as; not fast enough, not simplified enough and not intuitive enough. By creating Padgram, we brought a difference in the sense that we made it faster, simpler yet most powerful among all the other options.

We are proudly announcing that Padgram is the No.3 photo app in the US, and has got No.1 position in 60+ countries.

Our mission was to reach the No.1 Instagram iPad app in the world. To achieve that, we created interesting features, like the Emoji keyboad and self/cross promotion button. We also keep listening  to our users, as their feedback and opinion matters to us. We’re the first Instagram iPad app with portrait mode supported which was suggested by one of our users.

We’re so excited about Padgram’s rapid growth , so far we are No.3 photo app in the US, that won’t be the end of our great achievements. We will keep going further and further.

To end this post I would like to say , ” When we start a journey we always start it slowly….but then it gets faster and faster, the important thing is to start the journey and then you can head further than you thought you would…”

Download Padgram here, any comments are appreciated.

How we improved Padgram performance to “incredible” level (2)

As planned, I am going to write about “Choose the right JSON parsing library” in this session.

JSON format is popularly used between client and server communication. I’ve not met any open service without JSON interfaces yet. Padgram does a lot of JSON parsing when talking with Instagram server.

Occasionally, I find in a short period, 59% of CPU is used in parsing JSON data. That’s crazy! So I dig into the JSON library we used – SBJson.

The result is pretty obvious, the performance of SBJson is far from good. It ranks only 4th or 5th place compared with major competitors (SBJson is named “json-framework” in the chart):

  

You can read more here: https://github.com/johnezang/JSONKit

Obviously, JSONKit is the best among all competitors. After switching to JSONKit, I’ve never caught the CPU spike like before. (However, I didn’t get round to write testing program myself, I prefer to trust the genius guys in open source community)

In using JSONKit, there are some tips for speed that you should read on https://github.com/johnezang/JSONKit. Among them, we should use NSData over NSString to avoid the overhead to instantiate NSString objects. Here is our decode wrapper function that deals with this:

– (id)decodeData:(NSData *)data withEncoding:(NSStringEncoding)encoding
{

if (data == nil) {
return nil;
}

// this is important for performance, see here: https://github.com/johnezang/JSONKit
if (encoding == NSUTF8StringEncoding) {
return [[JSONDecoder decoder] mutableObjectWithData:data];
} else {
NSString *string = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:encoding];
return [string mutableObjectFromJSONString];
}

}

With proper JSON library, and incorporating with proper threading framework, Padgram gets great user interaction experience when scrolling at the same time of loading in the background. You could try Padgram from App Store.

How we improved Padgram performance to “incredible” level

Performance is very critical for an app to be successful. One Apple staff ever told me that an app with good performance is a must-have element for it to be featured, even it doesn’t mean one with good performance can be featured.

Performance was a headache for Padgram. We ever received a 1-star rating complaining the performance issue:

We were really upset with the 1-star rating. And we admit that’s a real problem in Padgram V2.2 or lower.

We profiled Padgram from ground, and finally improved its performance to a level that delights users. Like Versuri said:

Here I’d like to write down all my learnings and lessons. This is the first of the series.

(Before start, it worth mentioning that I read several sessions from WWDC regarding performance. And finally I stopped at “Session 318 – iOS Performance in Depth” from WWDC 2011 Session Videos. It highlights all ways to improve performance, while lack of examples. What I am doing here, is more examples, and focus on the ones that actually work for me. )

The first lesson we learnt is: properly adjust workload of UI thread and background thread to avoid UI thread blocked. This is a commonly seen advice. Here I just provide my example.

Instagram API is based on RESTFul API, every API call involves following procedure:

  • Prepare and send the request             <===== in background thread
  • Receive and parse response               <===== ideally, should all be in background thread
  • Update UI                                            <===== in main thread

To better balance the workload, we should only make bold parts above in main thread, and all others in background thread. This is theoretically right but hard to make it right as to the tricky networking library we use.

We use “ASIHTTPRequest” handle network requests. It forces all network completion blocks executed in main thread, regardless of which thread the request is prepared and sent. So in “Receive and parse response” part above, ASIHTTPRequest by default execute completion block in main thread, and we need to use GDC to make CPU intensive work (here in my case, parsing JSON data) executed in background thread.

// Prepare and issue the request in background thread
[httprequest.setCompletionBlock:^{

// the completion block will be executed on main thread
__block NSData *responseData = [httprequest responseData];

// dispatch to decode JSON data in low priority thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

// CPU intensive work, decode the JSON data
__block NSDictionary* jsonObj = [self decodeData:responseData withEncoding:responseEncoding];

// dispatch decoded data back to main queue for UI update
dispatch_async(dispatch_get_main_queue(), ^{

// update UI
……

});

});

});

In this way, we effectively avoid UI freezing when the app loads data while user interact with the UI. The typical use case is scroll Padgram to the end of a feed (Popular, My Feed, My Likes etc), it starts loading more. We successfully optimized to make the loading not impact user interaction.

To experience how it works, download and try Padgram from App Store.

Further lessons:

  • Choose the right JSON parsing library
  • Kill all offscreen rendering for scrolling animation performance
  • Always set shadowPath for shadowed borders
  • If possible, reduce view blending and hierarchy

I will write them asap.

How UI design affects Padgram downloads (stats inside)

A lot of people has suggested UI design (especially app icon) is important for an app. And it’s well proved in Padgram.

In Padgram 1.0, the design uses wooden texture:

Wooden texture is a fashionable design in 2012. It’s said to be good for photo viewing app. Our design combines wooden texture with transparent glass. It has the metaphor that your iPad is a wooden table, you put glass on it and photo over the glass. It’s good, isn’t it? While it’s hard to control from design perspective as it’s used in large scale. Using the app for long time easily causes aesthetic fatigue – it’s the case for our team members, and i bet it also happens on user end.

We realized wood texture might work its best when using only small pieces as decorator or some components like buttons, title bar or tab bar, but if using for the whole background, it’s not easy to control. The most stunning design with wooden texture is from App Design Vault. But after purchased and tried the template, it’s still not suitable for Padgram. And we did the refund (Thanks for App Design Vault to make the refund so easy).

And looking at the icons:

None of them are attractive enough, even for team members ourselves. Then it’s not surprising the download count is not good enough. For the first one month, we average 70 downloads (see below for stats). That’s really shame for a free app!

So we decided to redesign the app. It was painful, we didn’t add features, actually we remove many features. We dropped waterfall view (the reason is written here). We dropped portrait mode support. And we dropped wooden texture, replaced with a simple and light-weighted texture. Below is the new design:

And we hired a designer on Elance to design an icon. It costs us $50, but absolutely worth the money.

Since Padgram 2.0 released, the app downloads are increased for 3.5 times!

The soar was achieved under exactly the same condition: no promotion, no PR. For the reason why downloads are increased so much, the icon counts 70%. And of course the app itself, with unique value, is the key.

As a conclusion:

  • Good design really works
  • Simplify the app, make the core features work the best!
  • App Design Vault can be referred if you want to try some designs. It’s refundable, that’s important!
  • Icon is super important. Make sure you hired the right talent
  • Refer to Elance or Freelancer if you lack of design resource

After receiving many positive feedbacks, we’re confident with what we’re offering. We will start next stage – promotion. I’ll write down what we learned as time goes.

Check out Padgram App Page, or download it here.

How to install developer build to iPhone/iPad

For testing purpose, it’s often required to install an app onto a iPhone/iPad without jail-breaking (if your device is already jail-broken, the procedure will become pretty simpler. ). We’ve not found much useful article on web to document this, so we write it here:

First step: provide UDID to the developer

An UDID (Unique Device Identifier) is a sequence, combinations of alphabets and numbers with the length of 40 characters. It uniquely identifies your iPad. Install Get My UDID on your iPad, and use it to email the UDID to the developer.

Second step: developer sign the app with your UDID included

It’s the developer’s job, to save the words here. The developer should offer two files:

  1. a file with *.ipa extension
  2. a file with *.mobileprovision extension

Third step: install ipa onto the device

Get your iPad connected to your computer and iTunes launched.

  1. Uninstall the existing Padgram on your iPad
  2. Back to iTunes on your desktop, Drag the ipa and provision file to “Apps” panel. Accept to override the existing one when prompted.
  3. Choose your iPad in iTunes, check the “Apps” tab, make sure the app is selected, finally hit the “Sync” button, the app will be installed onto your iPad

Toubleshooting:

  1. Sometimes there could be a dialog prompt on device saying certificate is not trusted. Don’t hesitate to blame the developer if that happens 🙂
  2. We believe there are various strange issues out there, leave us message if you encounter any

“Trying to reach your satisfaction whatsoever….”