Recently I was working on an application that required WebView to be embedded in the same View Controller along with other native iOS controls. I decided to use the above framework, but knew that my ViewController class will have to extend WebViewController class of the framework. Though I could have done that, I thought separating the functionality of UIWebViewDelegate from the WebViewController would be a better design. So I replaced WebViewController with WebViewDelegate which implements UIWebViewDelegate protocol. I also removed getInitialPageName method from WebViewInterface.h . So here are the files in the new framework –
To explain how to use this framework, I will take a simple example where a ViewController contains mix of native controls and a WebView (BTW, because delegate functionality is separated from the ViewController, you can now have multiple Web Views in the same View Controller and can still use the framework). Let’s create a ViewController that has a text box and a button (native controls) and a WebView.
The WebView contains a combo box. There is no native combo box control in the Cocoa library, so this example might be useful to you if you want to create a combo box and don’t mind if it is created using HTML.
This is how the storyboard for this app looks like. Text box, add button and WebView are native iOS controls. Combo box is HTML control displayed in the WebView.
I created a ViewController class for the above view and called it RKMainViewController.
So unlike the previous framework, this class does not extend WebViewController. It extends UIViewController and implements WebViewInterface protocol of the framework. I have also created an outlet for the web view.
In the implementation of this class (RKMainViewController.m), I first declare local property (for WebViewDelegate) , action for ‘Add’ button and outlet for text box.
Of course, you need to connect outlet and action to controls in the storyboard. In the viewLoad function of this class, I create a new instance of WebViewDelegate, disable scrolling on it and load index.html from www folder –
I am returning two hard-coded list items in response to the call to loadList function. The result is returned as JSON string.
Action handler for ‘Add’ button gets text from the text box and calls JS function ‘addToList’.
Text to be added is passed in a dictionary, with key ‘newListItem’.
Now, let’s look at index.html. JS code in this file calls loadList function to populate the combo list and declares ‘addToList’ JS function, which is called from the native code, as shown in the code snippet above.
Notice that calliOSFunction (declared in iosBridge.js) is called from onReady function, which is called when the HTML body is loaded. The first argument to ‘calliOSFunction’ is the name of native function to call (in this case ‘loadList’). The second argument is array of arguments to be passed to the native function and the last argument is callback function that the native code will call when result is ready.
Result is passed as JSON string to the callback function handler. So we first parse the string and create a JS object. In this case we know that result is an array of strings. So we iterate over the list and add items to the combo box.
‘addToList’ function is called from the native code and takes JS object with the key-value pair. Expected key name is ‘newListItem’ and value is string to be added to the list.
In summary, this framework has a couple of advantages over the one I had created earlier, at the same time provides all the same functionality.
- Your view controller class need not extend the framework’s view controller class.
- It can support multiple web views in the same view controller.
You can download entire source code for the above demo application from here. The project is created with Xcode 5.0.