iPhone Programming : Connecting to the Network - Embedding a Web Browser in Your App

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
7/29/2011 5:32:54 PM
The UIWebView class allows you to embed web content inside your application. This class is the simplest but least flexible way of getting network content into your application. A UIWebView is best used to display content. If you want to manipulate the content programmatically, you should skip ahead a couple of sections and look at the discussion of the NSURLConnection class. However, there are a few tricks you can play to retrieve the displayed content from the UIWebView once it has been downloaded, and I’ll talk about them later in the section.

1. A Simple Web View Controller

There are a number of cases where you might want to load a URL and display a web page, but keep users inside your application rather than closing it and opening Safari. If this is what you need to do, you should be using a UIWebView.

So, let’s build some code that you’ll be able to reuse in your own applications later. The specification for this code is a view controller that we can display modally, which will display a UIWebView with a specified web page, and can then be dismissed, returning us to our application.

I’m going to prototype the code here, hanging it off a simple view with a button that will pull up the modal view. However, the view controller class is reusable without modification; just drag and drop the code out of this project and into another. This is also a good exercise in writing reusable code.

Open Xcode and start a new project, choose a view-based iPhone OS application, and when prompted, name it “Prototype”. The first thing we want to do is set up our main view; this is going to consist of a single button that we’ll click to bring up the web view. Click on the PrototypeViewController.h interface file to open it in the editor, and add a UIButton flagged as an IBOutlet and an associated method (flagged as an IBAction) to the interface file. The added code is shown in bold:

#import <UIKit/UIKit.h>

@interface PrototypeViewController : UIViewController {
IBOutlet UIButton *goButton;

-(IBAction) pushedGo:(id) sender;


Now, open the PrototypeViewController.m implementation file and add a stub for the pushedGo: method. As always, you have to remember to release the goButton in the dealloc: method:

-(IBAction) pushedGo:(id) sender {
// Code goes here later

- (void)dealloc {
[goButton release];
[super dealloc];

Next, we need to add a new view controller class to the project. This is the class we’re going to use to manage our UIWebView. Right-click on the Classes group in the Groups & Files pane in Xcode and select AddNew File, select the UIViewController subclass template from the Cocoa Touch Class category, and check the “With XIB for user interface” box. When prompted, name the new class “WebViewController”.

Three files will be created: the interface file WebViewController.h, the implementation file WebViewController.m, and the view NIB file WebViewController.xib.

After creating this new view controller, we need to leave Xcode for a moment. Double-click on the PrototypeViewController.xib file to open the NIB file in Interface Builder. Drag and drop a round rect button (UIButton) into the view and change its text to something appropriate; I picked “Go!”. (You can find the button in the Inputs & Values category of the Library.)

Next, click on File’s Owner in the WebView.xib window. In the Connections Inspector (⌘-2), connect both the goButton outlet and the pushedGo: received action to the button that you just dropped into the view, choosing Touch Up Inside as the action; see Figure 1. Make sure you save your changes to the PrototypeViewController.xib file and close it. We’re done with the PrototypeViewController class for now.

Figure 1. Connecting the UIButton to File’s Owner, the PrototypeViewController

Now we need to build our web view. Double-click on WebView.xib to open the NIB file in Interface Builder. Drag and drop a navigation bar (UINavigationBar) from LibraryWindows, Views & Bars, and position it at the top of the view. Then drag a web view (UIWebView) from LibraryData Views into the view and resize it to fill the remaining portion of the View window. Check the box marked Scales Page to Fit in the Attributes Inspector (⌘-1). Finally, drag a bar button item (UIBarButton) onto the navigation bar, and in the Attributes tab of the Inspector window change its identifier to Done. Once you’re done, your view will look similar to Figure 2.

After saving the changes to the WebView.xib file, close it and return to Xcode. We now need to implement the WebViewController class before we can connect the new UI to our code.

Open the WebViewController.h interface file. We want to make this class self-contained so that we can reuse it without any modifications. Therefore, we’re going to override the init: function to pass in the URL when instantiating the object. Make the following changes to the file (notice that I’ve added <UIWebViewDelegate> to the interface declaration):

#import <UIKit/UIKit.h>

@interface WebViewController : UIViewController <UIWebViewDelegate> {
NSString *theTitle;
IBOutlet UIWebView *webView;
IBOutlet UINavigationItem *webTitle;


- (id)initWithURL:(NSURL *)url;
- (id)initWithURL:(NSURL *)url andTitle:(NSString *)string;
- (IBAction) done:(id)sender;


Figure 2. Creating our web view in Interface Builder

In fact, to give a bit more flexibility to the class, I provided two different init: functions: initWithURL: and initWithURL:andTitle:. There’s also a done: method flagged as an IBAction that we can connect to our Done UIBarButtonItem when we go back into Interface Builder.

We’ve declared an NSURL and an NSString to store the URL and view title passed to our init methods, along with a UIWebView and a UINavigationItem flagged as IBOutlet to connect to the UI elements we created previously in Interface Builder.

Navigation Bars and Interface Builder

If you add the UINavigationBar to your modal view inside Interface Builder, as we have done here, it is not managed by a UINavigationController. This means you cannot set the title of the navigation bar inside your view controller using the self.title or the self.NavigationItem.title property.

There are several ways around this problem, but one of the easier ways is to declare a UINavigationItem IBOutlet in the view controller’s interface file, and then in Interface Builder connect this outlet to the UINavigationItem that contains the title (you’ll need to switch the WebView.xib window into list mode with Option-⌘-2 and expand the navigation bar).

Once this is done, you can set the title in the navigation bar from the viewDidLoad: or viewDidAppear: method using the title property of the instanceUINavigationItem IBOutlet variable that you declared. variable pointing to your

Now, open the WebViewController.m implementation file. We’ll start by implementing the two initWith methods. Add the following code to the file:

- (id)initWithURL:(NSURL *)url andTitle:(NSString *)string {
if( self = [super init] ) {
theURL = url;
theTitle = string;
return self;

-(id)initWithURL:(NSURL *)url {
return [self initWithURL:url andTitle:nil];

Next, we have to load the URL into the view, and we’ll do that in the viewDidLoad: method. Uncomment the viewDidLoad: method and add the lines shown in bold:

- (void)viewDidLoad {
[super viewDidLoad];
webTitle.title = theTitle;
NSURLRequest *requestObject = [NSURLRequest requestWithURL:theURL];
[webView loadRequest:requestObject];

Now we have to deal with what happens when the user dismisses the view by tapping the Done button. Add the following to the file:

- (IBAction) done:(id)sender {
[self dismissModalViewControllerAnimated:YES];

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
webView.delegate = nil;
[webView stopLoading];

Finally, we have to make sure we release our declared variables in the dealloc: method. Add the lines shown in bold to this method:

- (void)dealloc {
[webView release];
[webTitle release];
    [super dealloc];

We’re not quite done yet. Back in the PrototypeViewController.m file we still need to implement the pushedGo: method. Replace // Code goes here later with the code shown in bold:

-(IBAction) pushedGo:(id)sender {
NSURL *url = [NSURL URLWithString:@""];
WebViewController *webViewController =
[[WebViewController alloc] initWithURL:url andTitle:@"Apple"];
[self presentModalViewController:webViewController animated:YES];
[webViewController release];

Remember that since we’ve used the class in the pushedGo: method, we also now need to import the WebViewController.h header file into the PrototypeViewController. So, go to the top of PrototypeViewController.m and add this line:

#import "WebViewController.h"

We’re done in Xcode. Now we have to go back into Interface Builder and connect the web view to our controller code. Open the WebView.xib file in Interface Builder. Make sure you are in List view mode (Option-⌘-2) and expand the view completely, then click on File’s Owner. In the Connection Inspector:

  1. Connect the webTitle outlet to the UINavigationItem “Navigation Item (Title)”.

  2. Connect the webView outlet to the UIWebView “Web View”.

  3. Connect the done: received action to the UIBarButtonItem “Bar Button Item (Done)”.

Finally, click on the web view and connect the delegate outlet back to File’s Owner.

At this point, if you click on File’s Owner in the main NIB window and check the Connections tab, you should see something similar to Figure 3.

Save the NIB and return to Xcode. Click on the Build and Run button in the Xcode toolbar to compile and start the application in iPhone Simulator, as shown in Figure 4. Tap the Go! button and the Apple website should load in your view. Remember that you’re making a network connection here, so you might have to be a bit patient depending on the speed of your network connection.

Of course, users don’t like to be patient, and we currently don’t have a way to indicate to them that our application is doing something they need to be patient about. This is where the UIWebViewDelegate protocol comes in; we declared WebViewController as a web view delegate, but so far we haven’t taken advantage of that.

The delegate protocol offers two methods: webViewDidStartLoad: and webViewDidFi⁠nishLoad:. We can use these to start and stop the network activity indicator in the iPhone’s toolbar to indicate that we’re transferring data and the user should be patient. Add these two methods to WebViewController.m:

- (void)webViewDidStartLoad:(UIWebView *)wv {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

- (void)webViewDidFinishLoad:(UIWebView *)wv {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

But what happens if our URL fails to load? Even if we checked reachability before creating the view controller, what if we lose the network connection while the page itself is loading? The delegate protocol also provides the webView:didFailLoadWithEr⁠ror: method to inform us that something has gone wrong. Add the following to WebViewController.m:

- (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

NSString *errorString = [error localizedDescription];
NSString *errorTitle =
[NSString stringWithFormat:@"Error (%d)", error.code];

UIAlertView *errorView = [[UIAlertView alloc]
otherButtonTitles:@"OK", nil];
[errorView show];
[errorView autorelease];

Figure 3. The web view NIB file connected to the WebViewController

Figure 4. The initial main view (left) and the web view (right)

Since we said our view controller class is the UIAlertView delegate, we also have to declare the class as a UIAlertViewDelegate in the WebViewController.h interface file:

@interface WebViewController :
UIViewController <UIWebViewDelegate, UIAlertViewDelegate> {
... no changes to the code inside the declaration ...

With this change made, we can make use of the UIAlertViewDelegate protocol back in our implementation to dismiss the web view pane when an error is received loading our URL. Add the following to WebViewController.m:

- (void)didPresentAlertView:(UIAlertView *)alertView {
[self dismissModalViewControllerAnimated:YES];

We’re done. With these changes, the application can tell the user that it is doing something, and can handle any errors that occur when loading the URL. Click on the Build and Run button in the Xcode toolbar to compile and start the application in iPhone Simulator. Tap the Go! button and you should see the activity indicator spinning in the toolbar next to the WiFi signal strength icon as the application loads Apple’s web page. When it finishes, the spinner should stop.

Click Done, and then either turn Airport off or unplug your Ethernet cable. Now try again, and you should get something that looks like Figure 5, informing you that you no longer have an Internet connection.

Figure 5. The webView:didFailLoadWithError: method creates a UIAlertView and dismisses the web view when we fail to load the URL we passed to it

2. Displaying Static HTML Files

We can use the UIWebView class to display HTML files bundled into our project. In fact, we can add HTML documents to our project in the same way we dragged and dropped the images into the City Guide application; .

Suppose we’re going to use a web view to display a help document for our application. We could do so as follows:

NSString *filePath =
[[NSBundle mainBundle]
pathForResource:@"HelpDocument" ofType:@"html"];

NSData *htmlData = [NSData dataWithContentsOfFile:filePath];

if (htmlData) {
[webView loadData:htmlData
baseURL:[NSURL URLWithString:@""]];

We grab the file path to our bundled resource, create an NSData object, and pass this to our web view.

Embedding Images in the Application Bundle

Since we can specify the base URL of our web view, we can use a trick to embed small images directly into our application bundle by setting this base URL for our HTML document correctly. For instance, if we have an HTML document in the NSString variable htmlDocument, we could add this snippet:

NSString *filePath = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:filePath];
[webView loadHTMLString:htmlDocument baseURL:baseURL];

This will load the HTML document into our UIWebView. However, it will also set the base URL to the root of the application bundle and allow us to add images (or other content) into our application and refer to them directly in our document (or an associated CSS file):

<img src="image.png">

You should note that even if you store your images inside a folder in your Xcode project, they will be at the root of the application bundle file when you build and deploy your application.

3. Getting Data Out of a UIWebView

A UIWebView is primarily intended to display a URL, but if need be you can retrieve the content that has been loaded into the view using the stringByEvaluatingJavaScriptFromString: method:

NSString *content =
[webView stringByEvaluatingJavaScriptFromString:@"document.body.outerHTML"];
Other -----------------
- iPhone Programming : Connecting to the Network - Detecting Network Status
- Parallel Programming with Microsoft Visual Studio 2010 : Introduction to Parallel Programming - Software Patterns
- Parallel Programming with Microsoft Visual Studio 2010 : Introduction to Parallel Programming - Multicore Computing & Speedup
- Microsoft ASP.NET 3.5 : Web Services for ASP.NET AJAX Applications (part 2) - Consuming AJAX Web Services
- Microsoft ASP.NET 3.5 : Web Services for ASP.NET AJAX Applications (part 1) - Remote Calls via Web Services
- Microsoft ASP.NET 3.5 : AJAX-Enabled Web Services - Implementing the AJAX Paradigm
- The Art of SEO : Measuring Search Traffic (part 2)
- The Art of SEO : Measuring Search Traffic (part 1)
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Do Math
- Programming Excel with VBA and .NET : Tasks in Visual Basic - Interact with Users
- Context and Interception : The .NET Context
- Context and Interception : .NET Component Services
- Optimizing for Vertical Search : Mobile, Video & Multimedia Search
- Programming WCF Services : Data Contracts - Collections (part 2) - The CollectionDataContract Attribute & Dictionaries
- Programming WCF Services : Data Contracts - Collections (part 1) - Concrete Collections & Custom Collections
- iPhone Programming : The Image Picker View Controller - Adding the Image Picker to the City Guide Application
- iPhone Programming : Other View Controllers - Modal View Controllers
- jQuery 1.3 : DOM Manipulation - Inserting new elements
- jQuery 1.3 : DOM Manipulation - Manipulating attributes
- DirectX 10 Game Programming : Adding the DirectX Libraries
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us