Displaying Web Content

If your user interface includes a UIWebView object, you can display local content or content that is loaded from the network.

Loading Local Content

When loading local content, you can either create the content dynamically or load it from a file and display it using the loadData:MIMEType:textEncodingName:baseURL: or loadHTMLString:baseURL: method. The method in Listing 4-1 uses the loadData:MIMEType:textEncodingName:baseURL: method to load the contents of a PDF file into a web view.

Listing 4-1  Loading a local PDF file into the web view

- (void)viewDidLoad {
    [super viewDidLoad];
 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"iPhone_User_Guide" ofType:@"pdf"];
    if (thePath) {
        NSData *pdfData = [NSData dataWithContentsOfFile:thePath];
        [(UIWebView *)self.view loadData:pdfData MIMEType:@"application/pdf"
            textEncodingName:@"utf-8" baseURL:nil];
    }
}

The text encoding string has no effect on PDF data but is retained in the listing for example purposes.

Loading Content From the Network

To load content from the network, you create an NSURLRequest object and pass it to the loadRequest: method of your web view.

[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]]];

Because loading a web resource might take some time, you might display an activity indicator to indicate that the load is underway. You can do this by assigning a delegate to the web view and implementing the UIWebViewDelegate methods, as in Listing 4-2. The delegate displays an activity indicator when the load starts and hides it when the load ends. If there is a problem with the load, it creates an HTML error message and, using the loadHTMLString:baseURL: method, loads it into the web view for display.

Listing 4-2  The web-view delegate managing network loading

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    // starting the load, show the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
 
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // finished loading, hide the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
 
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    // load error, hide the activity indicator in the status bar
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
 
    // report the error inside the webview
    NSString* errorString = [NSString stringWithFormat:
                             @"<html><center><font size=+5 color='red'>
                             An error occurred:<br>%@</font></center></html>",
                             error.localizedDescription];
    [self.myWebView loadHTMLString:errorString baseURL:nil];
}

If, after initiating a network-based load request, you must release your web view for any reason, you must cancel the pending request before releasing the web view. You can cancel a load request using the web view’s stopLoading method. A typical place to include this code would be in the viewWillDisappear: method of the owning view controller. To determine if a request is still pending, you can check the value in the web view’s loading property. Listing 4-3 illustrates how you might do this.

Listing 4-3  Stopping a load request when the web view is to disappear

- (void)viewWillDisappear:(BOOL)animated
{
    if ( [self.myWebView loading] ) {
        [self.myWebView stopLoading];
    }
    self.myWebView.delegate = nil;    // disconnect the delegate as the webview is hidden
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

The loadRequest: example is taken from the UICatalog sample code project.