Showing posts with label Mobile. Show all posts
Showing posts with label Mobile. Show all posts

Friday, September 14, 2012

How we sidestepped an App Store catastrophe

UPDATE: The app has been approved since I originally wrote this post. The app review delay had nothing to do with technology choices, and Apple has been fairly quick to approve updates since.

I submitted Outbox's iPad app for review on July 10. It went into "In Review" status on July 24, where it has remained ever since. Actually, it was rejected once on August 22 because the demo account credentials I gave didn't work, despite server logs showing 2 logins on the demo account from Cupertino. I resubmitted, saw 4 logins the following day, and have heard nothing since. My expedited review request was denied. The request status update feature in iTunes Connect is a joke because it takes a week to get a response that the app is still in review, which of course I can see in iTunes Connect. Apple Developer Relations can't help because they can only contact the review team through the same channels I can. One of Outbox's founders even contacted a handful of friendly VPs at Apple for help, and still nothing.

So here we are 2 months later (and counting), still in review.

For a while we continued to plan our launch for "after we get approval" thinking that the app was bound to be approved soon since it had already been so much longer than the average review time, but the weeks kept slipping by and we were forced to delay our launch week after week. Finally, we came to terms with the fact that Apple will get around to approving (or rejecting) the app whenever they damn well feel like it. It could be tomorrow or it could be a year from now. The important lesson I learned is if your product lives in the iOS App Store you are forfeiting control over your release schedule. Have a backup plan.

Fortunately the Outbox iPad app is built with Javascript, HTML, and CSS. The app calls into native extensions for functionality like contacts and notifications as needed through PhoneGap, and makes heavy use of hardware accelerated transforms to get a native look and feel. So after a short discussion, we decided to launch a web app with support for iPad only (we haven't optimized for different aspect ratios or mouse interaction yet). This required almost zero additional effort because this is how we test the app most of the time anyway. The native bits that the app depends on degrade gracefully in a browser when they are not available. The only thing that needed to change was the email confirmation at the end of the signup process which now says "go to this URL on your iPad" instead of "download the app from the App Store". Our designer whipped up a screen with some instructions for the user to pin the app to the home screen when they follow the link from the confirmation email:


In some ways the web app experience is actually better than the app store version of the app. Nitro is available in chromeless web apps, but not in UIWebView, so Javascript execution gets about a 5X speed boost. At any rate, launching the web app beats the hell out of sitting around waiting when we could be making money and iterating on the product. Had we built a fully native application to begin with, turning around to build a web app would likely have taken weeks, if not longer. And if nothing else, it feels good to own our release schedule again.

We just launched in Austin, so if you live in Austin, try us out!

Saturday, September 1, 2012

10 tips for getting that native iOS feel with PhoneGap

At Outbox we have been hard at work building our iPad application with PhoneGap. I wanted to share some of the lessons my team has learned so far. All of the following tips have been tested on iOS 4, 5, and 6 with PhoneGap 1.8. Also note that these tips apply just as well to web applications running on mobile Safari.

Want more information about developing high quality PhoneGap applications, with in-depth explanations and working code examples? Check out phonegap-tips.com.

Tip #1 - Test on old hardware

Your app looks and feels great on that shiny new iPad 3 or iPhone 4S, right? Unfortunately, not everyone runs out to drop $500 whenever Apple releases a new toy. Get your hands on a first generation iPad or third generation iPhone. Always test on them first. If your app performs acceptably on on old hardware it is going to be blazing fast on the newer hardware.

Tip #2 - Use pre-emptive 3D transforms

If an element is going to be transformed in response to user interaction put an identity 3D transform on the element before any user interaction happens, for example:
-webkit-transform: translate3d(0px,0px,0px);
When the user first interacts with the element the initial movement will be much smoother.

Tip #3 - Show or hide elements with 3D transforms when possible

Invariably you will have some elements that need to be shown or hidden based on user interaction. For example, a modal dialog or menu of some sort. The easiest way to do this is usually display:none or visibility:hidden, however, you can achieve a significant speed increase by using a 3D transform to position the element offscreen. In my experience, using this technique to show or hide menus resulted in a 3-5X speed increase over display:none.

Tip #4 - Preload images

Even though your images are already stored on the iOS device there will still be a noticeable "pop-in" when the images are first displayed. I found CSS3 caching to be the best method for dealing with this issue. If you are not keen on enumerating and maintaining a list of every background image you use in your app, here is a jQuery plugin that will preload any background image referenced in your CSS.

Tip #5 - Phark image replacement does not play nice with 3D transforms

Image replacement by setting a large, negative text-indent is great for accessibility since screen readers will find the text and browsers will only display the image. However, the text-indent will make for unbearably choppy 3D transitions in mobile Safari (this is actually related to tip #7). Fortunately, there are alternatives to Phark that perform much better.

Tip #6 - Velocity scrolling!

Velocity scrolling is a super easy way to get a native feel in the scrollable portions of your app. It is simple to enable it on any scrollable area with a CSS rule:
-webkit-overflow-scrolling: touch;
That's it! However, be warned, Apple's current implementation is a little bit buggy.

Tip #7 - Respect maximum texture sizes

Each iOS device has a maximum texture size. If you try to smoothly transform an element larger than the maximum texture size, the element will be broken into smaller tiles before the transform is applied, and this a very slow and ugly process.

Tip #8 - Hide large, off-screen images

If your app displays many large images, hide the images that are off-screen. Otherwise, it doesn't take many large images to unceremoniously crash your app. Both display:none and visibility:hidden work just fine, but tip #3 will not cut it here.

Tip #9 - Eliminate tap event delays

It takes mobile Safari about a third of a second (300 milliseconds) to decide that a touch start event followed by a touch end event should be synthesized into a click event. Plenty of frameworks, such as jQuery Mobile, have "tap" handling code that can eliminate this delay for you.

Tip #10 - Disable tap highlighting

Have you ever noticed that translucent gray highlight mobile Safari puts on links and buttons when they are clicked? It is a dead giveaway that your app is not native, but you can get rid of it by making the highlight color completely transparent:
-webkit-tap-highlight-color:rgba(0,0,0,0);
Overall we're loving PhoneGap at Outbox. Hopefully these tips will help make a few more happy PhoneGappers!

Update
This post got picked up by Hacker News. See the discussion here.