
A Primer on Hybrid Apps for iOS - aaronbrethorst
http://www.cocoacontrols.com/posts/a-primer-on-hybrid-apps-for-ios
======
lazerwalker
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
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

~~~
lukifer
For those of us who code in web-land, a delay of one hour would be appalling,
let alone an entire week. (And of course even then, it relies on user action,
and so will never be 100%.)

~~~
pvidler
One hour is appalling? Are your users that dependent on running the latest
version of your app, or is it a concern about fixing show-stopping bugs in
reasonable time?

~~~
bmelton
I'm sure he just means that on the web, the turnaround from bug to bugfix to
patched instance is near instantaneous.

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.

~~~
pvidler
True, but surely you can retain the ability to alert or otherwise communicate
these things to your users without putting any of the main GUI in a web view?
Minor bugs require only a little communication and major show-stoppers can be
avoided with care.

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.

~~~
bmelton
As an 'app owner', it perhaps benefits you to possess the ability to preserve
what you've paid for. In some cases, I'm sure this actually is a benefit, as
in the times updates are negative, or take away functionality or change the
way they do things. In most cases though, it just means that you aren't up to
date with what is current, which may or may not be a bad thing.

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.

~~~
lukifer
Strictly speaking, none of us "own" the majority of the software we pay for.
We license it, and we are entirely at the mercy at the vendor's terms, with
the only recourse being not buying it in the first place.

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.

~~~
bmelton
I get the implication, and while that wasn't the point I was making, the
purchase of a self-contained app from the app store is _essentially_ the same
thing as owning the app.

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.

------
peterkelly
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
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.

~~~
lukifer
There is also the advantage of instant deployment, and always being up-to-
date. I don't think hybrid is the best fit for all apps, or even most, but it
can work well and create a good experience for certains types of apps.

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.

------
msgilligan
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
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
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
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
Hit me up with a link to a better benchmark and I'll happily include it.

------
sumukh1
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
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.

~~~
daniel_sim
What you need to do is use a 'touchUpInside' event, there are a couple wwdc
preso's that cover it. Basically you compare coords of a touchend event to the
coords of the target. Touchend events fire instantly so you dont have to worry
about the 300ms click delay. Dug this out of some old code, wont work out of
the box but you get the gist. <https://gist.github.com/3067704>

