top | item 4212153

A Primer on Hybrid Apps for iOS

82 points| aaronbrethorst | 13 years ago |cocoacontrols.com

30 comments

order
[+] lazerwalker|13 years ago|reply
The problem with people complaining that hybrid iOS apps don't "feel right" is that the defining characteristic of a well-made hybrid app is that you don't notice it's a hybrid app, meaning the only apps people tend to consciously associate with being 'hybrid apps' are the mediocre ones.

For every web-based iOS app that's clunky and slow like Facebook, there's another one like Quora or OKCupid or even the iOS App Store that is almost indistinguishable from a native app, save for a few minor telltale giveaways (one of the most common ones is showing a loading icon while you load in an entire view instead of rendering a view's components piecemeal as they're ready).

The problem is that many developers who go with a hybrid app solution do so because they think it'll be easier or quicker than an all-native app, especially if they need multiplatform support. Doing a hybrid app correctly can in many cases require much more work than simply doing a native app, both technically (there are a lot of very tricky caching issues, since UIWebViews don't properly handle cache manifests) and design-wise in terms of nailing the behavior and feel of a native app. Hybrid apps are neither a complete usability disaster nor a silver bullet that gives you a 'write once, run anywhere' utopia.

[+] thomasjoulin|13 years ago|reply
I don't know about Quora and OKCupid, but the iOS App Store is a terrible app ! Scrolling sometimes hides the whole table view, the sign out button are not responsive, and don't even try to open past purchases if you have a lot.

I agree with you on the last part though. I'd recommend native app with a good design that makes it flexible via server changes. For big changes, the app store updates is usually just a one week process anyway

[+] pvidler|13 years ago|reply
> or even the iOS App Store that is almost indistinguishable from a native app

Are we using the same app store? It's awful! It's painfully slow and it frequently 'forgets' what I was doing when I press the back button after viewing an app's details (search filters and list positions, to name a few).

[+] potatolicious|13 years ago|reply
I haven't used the Quora app, but the OKCupid app is pretty bad - it frequently gets itself into a bad state (especially if the app hasn't been opened in a while) where it will sit at the loading screen forever. It's also painfully slow, navigation is incredibly laggy. It's functional, but hardly great.

It's not the most obvious UIWebView-wrapped app ever, but it's still fairly evident.

I have only ever seen one hybrid app done well - and that's the LinkedIn app. Every single other hybrid app (including Apple's own App Store!) is slow, buggy, and just unpleasant to use.

[+] gojomo|13 years ago|reply
I've been trying to get a UIWebView to use a cache manifest with no luck. Is it hopeless or is there a trick/writeup I'm missing?
[+] gurkendoktor|13 years ago|reply
In addition to everything that's been mentioned about the App Store, it also has the most telling mark of a hybrid app: It occasionally crashes on the iPad 1 on iOS5 because it runs out of memory, especially if there is still something running in the background. Even Safari itself crashed regularly until I realized that Skype had been running in the background for days.

IMHO, hybrid apps would be much nicer if UIWebView could just manage its appetite for RAM a little better.

[+] peterkelly|13 years ago|reply
I'm of the view that in general, it's better to code directly to the iOS APIs rather than trying to implement everything in a UIWebView. Having said that, I've just spent a substantial amount of time developing a word processing application (UX Write), which uses a UIWebView for all document layout, and a large amount of "backend" code in javascript for performing editing operations. All the UI code however is written in Objective C and the Cocoa Touch APIs.

The advantage of using native controls it it provides a much greater integration with the rest of the operating system, and makes it easier to make your app work in the same manner as other apps. For example, there are many features of iOS that are not exposed through javascript APIs, and for that you have no option but to use native code. Nonetheless, I like what Microsoft is doing with providing javascript APIs for metro development, and though I haven't tried it myself, it looks like a good approach.

There are a number of serious problems with the current UIWebView which are also holding it back as development tool:

- You have very limited control over touch events. In my case, I completely disabled all default event handling on the web view, and implemented my own touch event handlers in Objective C, which pass the events through to javascript.

- Selection is broken. You can access the selection, but not modify it. I spent several weeks completely reimplementing the selection & cursor mechanism because of this. One positive outcome though was it gives me much more fine-grained control over user interaction issues.

- contentEditable is also broken. I spent probably 3-4 months reimplementing this functionality myself in javascript to make it usable

- Interfacing between Objective C and Javascript is tricky. Going from ObjC -> JS is fast, but going in the other direction using the technique from the article is painfully slow. There a ways to work around this but it's inelegant and doesn't allow return values from callback functions.

- Lack of Nitro support, as discussed elsewhere. It turns out that for my particular needs performance is quite acceptable, but for more compute-intensive apps like games it's a must. I can understand Apple's desire to prevent W+X permission on memory, but this could be solved by running JS code in a separate process and communicating with the host process via shared memory.

Apple have done some amazing things with WebKit, but the iOS port leaves a lot to be desired. I would really like to see them improve these apps so people can better integrate web content & backend functionality. But I still think you should be using Cocoa Touch for your UI.

[+] msh|13 years ago|reply
I Think the only good reason to do a hybrid app is crossplatform portability, if you don't have the resources to do multiple native apps.
[+] msgilligan|13 years ago|reply
This the best article or post on Hybrid apps I have seen in a long while.

My one complaint is that he doesn't seem to acknowledge the possibility of a "minimal Objective-C" app (i.e. mostly HTML-based) that is tailored to iOS and uses in-app storage for most of the UI elements. We need more discussion on methods to make the mostly-HTML approach to work better. The post is a great start.

[+] kennywinker|13 years ago|reply
Whenever hybrid apps comes up, I never hear mention of Instagram. I can't find any specific details on their app stack, but as this screenshot (http://i.imgur.com/p00E2.png) shows, they are definitely using web views for parts of their UI (timeline view).
[+] alexanderblom|13 years ago|reply
The timeline/feed is not a WebView from what I can see. The news part/tab is though (which is displayed in the screenshot).
[+] jdc2172|13 years ago|reply
Why do they link to a javascript benchmark that only features differences between ios safari versions? Javascript had terribly performance in ios 4 - if they did basically anything it would be much faster. Android's chrome has a much faster javascript engine.
[+] aaronbrethorst|13 years ago|reply
Hit me up with a link to a better benchmark and I'll happily include it.
[+] sumukh1|13 years ago|reply
Another example of a hybrid app is the iOS (and Mac) App Store. A significant amount of the views are basically HTML.

By far, the biggest improvement one can do is to get rid of the 300ms or so delay on a UIWebView

[+] peterkelly|13 years ago|reply
Incidentally, the 300ms delay is not to prevent accidental touches, it's so the system can detect the difference between a double tap and a single tap. If you don't make a second tap within 300ms, it goes and fires the single tap event. But it can't do that until it knows for certain that it's not simply the first tap in a double-tap sequence.

The solution to this, if you're not using double-taps, is to respond to the event when it enters the initial phase (then the finger is pressed), rather than when it's released. I'm not sure if you can do this through javascript, but I know it's possible in Objective C by either overriding – touchesBegan:withEvent:, or implementing your own gesture recogniser.