A Primer on Hybrid Apps for iOS
cocoacontrols.com
cocoacontrols.com
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.
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
Step 1, Notice bug
Step 2, Fix bug
Step 3, Deploy bugfix
The steps between 1 and 2 could obviously take a variable amount of time, but Step 3 is 'near instantaneous' on the web. The thought of having to relinquish deployment to somebody else, and that somebody else possibly taking a week to just alert users that there IS a bug fix, much less the time it takes for those users to see and apply the fix, that's a relative eternity.
Maybe I'm a little biased on this, but I hate that a web app I might be relying on can change completely (both in GUI and functionality) without my consent or involvement; at least with app updates I can get some warning and release notes -- a chance to extract my data before taking the plunge... but I guess I'm getting a bit off-topic.
It is offtopic, but still interesting. One supposes that is the reason why apps cost a set amount of money (usually) while web apps are usually a subscription model. That is of course questionable when the app uses web views to your server, as those customers always cost you money so long as they're using the app vs. standalone apps (like games and the like) where you truly are making a one-time purchase.
It's yet another area where the nature of software and the networked world breaks our object-oriented intuitions in ways we're still trying to resolve in the social contract.
You've exchanged money for a good, and as the app owner there aren't any readily available means of getting the good back from the owner should you disapprove of how they're using it, just like it would be with a tangible good. Obviously copyright still stays in effect so their ability to copy, resell, yadda yadda are still restricted, but otherwise it's theirs.
That said, in this day and age, fewer and fewer apps are completely self-contained, and/or work without being plugged in to something, so it's effectively a moot point.
At the same time, I understand your feelings about wanting to be in control of updates. (As a user, I'm even upset that Apple doesn't allow the user to roll back.) But when devs can count on every user being up to date, it enables them to push new features more quickly instead of having to write backwards compatibility, fallbacks, etc.
The question of who owns and controls code is a sticky one, and I'm not sure there's an ideal answer; to the extent that there is, I think it varies highly by the nature of the 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).
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.
Either way, they obviously need to fail a little more gracefully, which should be a solvable problem.
IMHO, hybrid apps would be much nicer if UIWebView could just manage its appetite for RAM a little better.
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.
But as other commenters have noted, it should never be seen as a "time-saver" for anything beyond trivial functionality; the little quirks of each browser runtime must be paid their due, with the user experience and performance in mind.
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.
By far, the biggest improvement one can do is to get rid of the 300ms or so delay on a UIWebView
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.