Callbacks from webView to JavaScript: sharing data between native code and html
It is a very common technical problem with eDetailing (and other apps using html5 to display content), that you need to share data between your native iOS (or Android, Windows) code and your html presentation. And the code can and does get messy.
When you try to share data between your UIWebView and your JavaScript library, you’ll end up with something like this.
The problem with that is obvious: you have your business logic defined, then you call the iOS method and the application will at some point call some other method as a callback. You end up storing states all over the global scope and trying to guess, where exactly in the process are you at the moment.
Luckily there have been advences in JavaScript lately, which make this problem go away:
- Promises
- Observables
- Generator functions
Our goal was to remove this break between the sender and the callback in the workflow and be able to focus on the business logic, without having to care about where and how the data is received: I just want a Promise returned when calling the native function.
Catching The Callback
First off, we need to solve the issue of the break and catch the callback without leaving the sender. For this, we can use the Observer pattern, namely ReactiveX. We observe when the callback gets called:
Returning The Promise
Now we can simple wrap all this in a Promise and resolve it when the subscriber receives the data. I also added a timeout, so the code won’t hang in case of an error in the iOS code. Also, we use Bluebird as it is much faster then the native Promise.
Clean Business Logic Code
Now back to the business logic. Thanks to the Promise, I do not have to leave the scope of my business logic function. Using co (or simple generator functions), will help to keep the code even cleaner.
And as you have a limited set of functions to call, you can create a nice, abstract and generic library for all your interactions with your native iOS code.