One of the easiest ways to connect to the internet is to use the UIWebView class, which gives you full access to web pages of any sort. In some ways, this class is of limited utility, because it largely duplicates Safari, and Apple isn’t interested in approving applications that duplicate their existing technology. But there are clearly situations where you’ll want a program to be able to refer to some specific web pages, and that’s what UIWebView is for.
The class is easy to use—we included it in simple examples way back in topics 3 and 4. The only real complexity is in building an NSURL or NSURLRequest object to get your web view started, but that process follows the methods you’ve already seen.
Calling up the web view
The two main ways to fill a web view once you’ve created it are listed in table 14.4. Most frequently, you’ll start with an NSURLRequest, which you must create using the two-step process we described in the previous section; but you can also load a web view with an NSURL and an NSString. A few other init methods can be found in the class reference.
Table 14.4 Methods for loading UIWebView
Method |
Summary |
loadHTMLString:baseURL: |
Loads a page from a URL and a string |
loadRequest: |
Loads a page from an NSURLRequest |
Assuming you use the more common NSURLRequest method, you can put together all the lessons you’ve learned so far, which is just what you did back in topic 3 when you created your first UIWebView:
When you have a UIWebView, you can start working with it. The five UIWebView methods and properties of particular note are summarized in table 14.5.
Table 14.5 Some sterling UIWebView options
Method/Property |
Type |
Summary |
goBack |
Method |
Moves back a page; check canGoBack property first |
goForward |
Method |
Moves forward a page; check canGoForward property first |
reload |
Method |
Reloads the current page |
scalesPageToFit |
Property |
Boolean that determines whether the page is zoomed into a viewport and whether user zooming is allowed |
We think the most exciting options are the goBack, goForward, and reload methods, which give you some control over how the UIWebView moves among pages. Similarly, the loadRequest: method can be continually rerun if you want to move a user through multiple pages, treating the UIWebView more like a web slideshow than a browser.
WARNING In our opinion, the scalesPageToFit property doesn’t work correctly at the current time. It always scales the page as if the UIWebView were full screen, and it leaves a less than optimal view if you create a small UIWebView, as you’ll do in the next example. As of iOS 4.0, this has yet to be resolved.
You must always load NSURLs using the loadRequest: method of NSURLRequest that we’ve laid out here to load pages into your web views.
Managing the web view delegate
One critical element we haven’t discussed previously is that you can set a delegate to manage a few common responses. You must follow the UIWebViewDelegate protocol, which lists four methods, described in table 14.6.
Table 14.6 Managing UIWebViews with delegate methods
Method |
Summary |
Called prior to content loading |
|
Called after content begins |
|
loading |
|
Called after content finishes loading |
|
Called after content fails to load |
Together with the UIWebView methods, these delegate methods give you considerable power. You can use them to load alternative web pages if the preferred ones don’t load. Or, continuing the slideshow analogy, you can use them to continuously load new pages when old ones finish. All those possibilities highlight the ways you may be able to use the UIWebView as more than a Safari clone.
Thumbnails: a web view example
As we’ve previously stated, UIWebViews are easy to set up, and we’re not going to spend a lot of time on a coding sample. Listing 14.2 presents a simple example that creates a set of web page thumbnails, similar to the startup page of the Google Chrome browser. It uses delegates first to get rid of UIWebViews that don’t load and later to zoom in on the one the user selects.
You should initially create it visually by laying out four UIWebViews on your interface. Make sure they’re set to scale, and set their delegates to be the view controller.
Listing 14.2 A thumbnail web viewer
To start with, you read a set of (exactly) four URLs from a file and use the NSString method componentsSeparatedByString: to turn them into an NSArray that you use to seed your web views O. After that, it’s a question of responding to delegation messages.
The webView:didFailLoadWithError: method C shows off some valuable techniques for both debugging and error management. You should use NSLog when you want to do a printf-style reporting of runtime variables. It outputs to /var/log/system .log when you run it in the Simulator.
In a UIWebView, two error codes come up with some frequency: -1003 is "Can’t find host," and -999 is "Operation could not be completed." This example ignores -999 (which usually means the user clicked a link before the page finished loading); but in the case of a -1003 failure, you dismiss the web view.
To start with, you read a set of (exactly) four URLs from a file and use the NSString method componentsSeparatedByString: to turn them into an NSArray that you use to seed your web views O. After that, it’s a question of responding to delegation messages.
The webView:didFailLoadWithError: method C shows off some valuable techniques for both debugging and error management. You should use NSLog when you want to do a printf-style reporting of runtime variables. It outputs to /var/log/system .log when you run it in the Simulator.
In a UIWebView, two error codes come up with some frequency: -1003 is "Can’t find host," and -999 is "Operation could not be completed." This example ignores -999 (which usually means the user clicked a link before the page finished loading); but in the case of a -1003 failure, you dismiss the web view.
Debugging
We haven’t talked much about debugging your SDK program in this topic, primarily for reasons of space. Here’s a short overview of our favorite techniques:
Xcode itself provides the best debugging. Pay careful attention to autocompletion of words and note when an expected autocompletion doesn’t occur, because that usually means you didn’t set a variable correctly.
Always carefully consider the warnings and errors that appear on compilation.
Finally, after you’ve finished with your program, you should run it through Instruments to check for memory leaks.
For more information, see "Xcode Debugging Guide," "Debugging with GDB," and "Instruments User Guide," Apple articles that contain comprehensive explanations of those subjects.
Finally, the webViewDidFinishLoad: method © zooms in on an individual web view (dismissing the rest) after a user clicks a link and the page loads. Realistically, this should occur whenever the user touches the web view; but we wanted to show the UIWebView delegate methods, so we chose this slightly more circuitous route.
And that’s it—a simple web thumbnail program, as shown in figure 14.2. It could be improved by giving the user the ability to manage the selected URLs and by polishing the way the user selects an individual page (including an option to return to the thumbnail page afterward). For our purposes, though, it does a great job of demonstrating some of the intricacies of the UIWebView.
Before we finish with web views, we’ll look at one more example. In topic 10, we talked about how Core Location would be better served when we got into the world of the internet. In section 14.5.4, we’ll look at the first of two Core Location internet examples.
Figure 14.2 As shown on an iPhone, the thumbnail web views load on the screen.