Sunday, January 3, 2010

Displaying Web Pages within an app via a custom WebViewController

I’m always perplexed why so many iPhone apps, when linking to a web site, choose to exit the app and launch Safari. It’s a very simple process to include a UIWebView and doing so makes for an easy way to keep someone within an app- leading to a smoother user experience.

About a year ago I made my own WebViewController for making the process of embedding a web page in an app even easier. I use this custom class in most of my apps and since I find it useful, I figured other developers might as well. As the name implies, it’s a UIViewController that contains a web view. It is designed to be used as a simple full-screen web browser, providing only a back, forward, and reload button, along with an option to relaunch the web page in Safari. This way, if the user really wants to leave your app while viewing the web page they can choose to, but it’s their choice.

The class also supports any view orientation, so once a web page is displayed, the user can rotate the device and the web view will also rotate.

You can download the complete WebViewController class file here.

Here’s an example of how it looks within the JAZZ.FM91 app in both portrait and landscape mode:

iPhoneSimulator.KcJeRT2AAV4j.jpg​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​iPhoneSimulator-landscape.ga5rNR5GeTFf.jpg

Since this class is a view controller, it’s pretty simple to use. You can either include it using all code, or can use it via Interface Builder. If you are comfortable including custom view controllers in your projects, you probably don’t need to read any further. But, if you are fairly new to XCode, Objective-C, and Cocoa, here are some more details for integrating this custom WebViewController class.

All in Code

Here’s an example without using InterfaceBuilder. First, download the class file, unzip it, and add the WebView folder and its contents to your project.

Then, add the necessary import line in whichever class file you choose to be using it in:

#import "WebViewController.h"

Then, add the following lines to be executed when you want the web view to be displayed:

        WebViewController *webViewController;
        webViewController = [[WebViewController] alloc] initWithNibName:@"WebViewController" bundle:nil];

        [self presentModalViewController:webViewController animated:YES];
        [webViewController release];        
        webViewController.delegate = self;
        [webViewController loadBrowser: [NSURL URLWithString: @“http://stormyprods.com”]];


In the above code, you may have noticed we registered the containing class as the delegate for this controller. This custom WebViewControllerview has a protocol (dismissWebView) for notifying its delegate when it should be dismissed. So, we should also implement that so we can dismiss the modal view at the proper time. In the class which contains the above added code, also add this new class method for handling the WebViewController’s protocol:

- (void) dismissWebView
{
        [self dismissModalViewControllerAnimated:YES];
}

And that’s it!

In the above example, we added the WebViewController as a modal view, but it could also have been added in any other way you would normally add a UIViewController. It could be one tab in a set of tabs, etc.


Using WebViewController via Interface Builder

If you were using Interface Builder (which I recommend whenever possible) you can do it as follows.

In whatever class you want to include this WebViewController, add the import for the .h file:

#import "WebViewController.h"

Then, add the webViewController to the class as an IBOutlet:

        IBOutlet WebViewController *webViewController;

Hook up this outlet in Interface Builder to a view controller object, and using the Inspector change the class identity to WebViewController. It should look something like this:

InterfaceBuilder1.3a5vQsW51hJm.pKiXSUCNcYOO.jpg

Then, when you want to have this WebViewController displayed, you would do it something like this:

        [self presentModalViewController:webViewController animated:YES];
        webViewController.delegate = self;
        [webViewController loadBrowser: [NSURL URLWithString: @“http://stormyprods.com]];

Note how this code is very similar to the earlier “code-based” method of displaying the WebViewController, but in this case we are not creating the class and we are not releasing the class either, since the creation or release is done behind the scenes by glue provided automatically by using Interface Builder.

And, finally, we’d still need to implement the protocol for dismissing the web view controller when it wants to go away:

- (void) dismissWebView
{
        [self dismissModalViewControllerAnimated:YES];
}

3 comments:

Andiih said...

Hi

Thanks for the article.

I notice there is an extra ']' in the alloc init.

What is in your reachability.h - it doesn't seem to be the same one as the apple demo projects as you call a C function?

alberto said...

This looks great! However, the custom reachability class is a show stopper...

Graham Cartwright said...

Great post, I managed to get right up to the error that has previously been commented on - the reachability.h issue. I tried downloading that file from Apple and it seemed to work better, now I just have one error with "implicit declaration of function 'isNetReachable'" in the WebViewController.m file... I have tried and failed to get rid of this... any further help for a nOOb?


All content copyright © 2009  Brian Stormont, unless otherwise noted.   All rights reserved.