How to use the UIWebView in iOS Applications


  • Share on Pinterest

More and more iOS applications now have their own internal web browser using UIWebView to get around multi-tasking issues on the devices. I'm going to show you how you too can include a simple web viewer in an application. Perfect for things like online help pages or sign-up account creation without taking the user away from your application.

Create Starting Application

Start by creating a Single View Application and be sure to select “Swift” as the language.

Select the Main.storyboard and the new viewController, we are going to embed this view in a Navigation Controller by going to the menu and selecting Editor > Embed In > Navigation Controller. We are doing this so we can create a separate view controller to keep our code clean and easy to read during this tutorial.

Back on our viewController add a button with a label of your choosing, I'm going with “Visit Web Site“. I also added basic constraints to keep the button centered on the view, you can read about basic constraints on this post I wrote covering basic constraints and auto-layout if you are not familiar with them.

Now Add a new viewController to the storyboard, drag the object from the library to the editor is probably the fastest way.

Right click and drag from the “Visit Web Site“ button to the newly added viewController to create a segue, I went with “Show” for the Action Segue. This completes the initial set-up that should be familiar by now, if not I have plenty of posts on my site to get you to this point even if you have not done any iOS development before.

Add Segue

If you want to be sure everything is working fine then go ahead and test the application either on a device or in the simulator. You should be able to navigate back and fourth using the button and standard navigation controls.

Adding the UIWebView Object and Custom UIViewController Class

Bring up the second view controller that we linked our button to and drag a “Web View” object from the library to the view controller on the storyboard. By default it will size to fit the view and that is fine for our purposes right now.

Web view added to view controller

We are going to add a new UIController class for the web view controller, with the project selected in the file list to the left in Xcode File > New > File and choose “Cocoa Touch Class” from “iOS Source” menu on the left of the sheet that appears. Make sure to select “UIViewController” as the subclass and ensure that Swift is selected as the language. We do not need a xib file so uncheck the box if it is checked then click “Next”. Some times Xcode can create the file in an odd place on the file list, so check where the new file ended up and move into the project if needed.

WebViewController.swift

The new file will open in the editor but before we go any further let us assign this new class to our web view. Go back to the “Main.storyboard” file to bring it up in the editor, with our view controller selected (web view remember not the one with the button!) go to the “Identity Inspector” in the panel to the right of Xcode, you can use the keyboard shortcut of Option Command 3 to get there quickly.

You will see at the top a section called “Custom Class” and a dropdown that might already be selected for you. Go ahead and either select from the dropdown or start typing the name of the new class file you just created, auto-complete should try to help you. This assigns our new class to this view controller where we can write code that will only effect this view.

Assigning custom UIControllerClass

Coding up the Web View Magic

Now we are going to focus on getting the web view to load a web page, to keep things simple we are going to call a function that gets called once the view is loaded, we will set-up the URL in code rather than have it entered by the user and then load that web page.

We need a way to talk to our UIWebView so go ahead and create an @IBOutlet, again my preferred method is to simply right click on the web view object and drag over to the view controller in the assistant editor. You should end up with something like

@IBOutlet weak var webViewer: UIWebView!

Now we need to create our function that we will call from viewDidLoad()

func loadWebPage() 
let url = NSURL(string: "https://peterwitham.com")
let request = NSURLRequest(URL: url!)
webViewer.loadRequest(request)
}

Breaking this down we first create a new URL and populate it with a string, then we create a new NSURLRequest and provide it the URL we created. Finally we tell our UIWebView to load a request which is our newly created NSURLRequest.

In the viewDidLoad() method add a call to our newly created method. You should end up with something like

override func viewDidLoad() 
super.viewDidLoad()

// Do any additional setup after loading the view.
loadWebPage()
}

If you run the application and go to the web viewer it should load the web page, it will probably take a few seconds depending on how nicely the Interwebs are playing when you try it.

iOS Simulator - pw_com loaded

Hmmmmmm wait, that's a good point! We currently do not know when the application is loading the page, we should create a responsible UI that gives the user some feedback whilst it's doing something right? OK we will, we should show the spinner that users see in the top status bar during network activity.

Delegate and Spin Me Right Round

To achieve what we are looking for we need to turn to delegation, a common theme in iOS development, if you are not familiar with delegation I have a post on getting started with the UIPickerView that covers delegation basics. The reason we need to be a delegate is so the UIWebView can tell us when loading starts and finishes.

Go ahead and change our view controller class to be a delegate of UIWebViewDelegate

Class WebViewController: UIViewController, UIWebViewDelegate

Now we need to satisfy the requirements of being a delegate … great power, responsibility and all that!

We are going to utilize three methods

webViewDidStartLoad:

When we start loading data this method is called and we can use it to do anything we want to indicate something is happening but not finished.

webViewDidFinishLoad:

When the view has finished loading data this method gets called and we can clean up our UI.

webView:didFailLoadWithError:

If for some reason we fail to load the page then this method gets called and we can respond and let the user know in a meaningful way.

First we will show the loading spinner in the status bar when starting to load the page

func webViewDidStartLoad(webView: UIWebView) 
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}

No prize for guessing we do the reverse when loading is complete

func webViewDidFinishLoad(webView: UIWebView) 
    UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}

Now we need to handle any pesky errors that the Interwebs will throw at us. For this tutorial we will simply remove the loading indicator and show a statement in the console. Ideally you might want to show an alert ([Post on how to display an alert][4]) or some other nice way to handle the problem.

func webView(webView: UIWebView, didFailLoadWithError error: NSError) 
    UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    println("There was a problem loading the web page!")
}

All we have to do to finish up is tell our UIWebView that our controller will act as the delegate for it, since my @IBOutlet is called “webViewer” all that is needed in the viewDidLoad just above our method call for loading the web page is

webViewer.delegate = self

Here is the entire code of the new view controller

//
//  WebViewController.swift
//  WebTest
//
//  Created by Peter Witham on 5/21/15.
//  Copyright (c) 2015 PeterWitham. All rights reserved.
//

import UIKit

class WebViewController: UIViewController, UIWebViewDelegate 

    @IBOutlet weak var webViewer: UIWebView!
    
    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        webViewer.delegate = self
        loadWebPage()
    }

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */
    
    func loadWebPage() 
        let url = NSURL(string: "https://peterwitham.com")
        let request = NSURLRequest(URL: url!)
        webViewer.loadRequest(request)
    }

    func webViewDidStartLoad(webView: UIWebView) 
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    func webViewDidFinishLoad(webView: UIWebView) 
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webView(webView: UIWebView, didFailLoadWithError error: NSError) 
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
        println("There was a problem loading the web page!")
    }

}

Run the application and you should now see the spinner appear during load and disappear after the page is loaded. The homework for you is to figure out what you need to do to resize the loaded web page to fit inside the view after it has been loaded.

Wrap Up

I have covered the basics of getting a UIWebView up and running in an iOS application, there is so much more you can do but this is enough to get you started. I recommend playing around with the object and seeing what else you can do. The power to just pop up a web page or entire web application inside an iOS app is very useful for so many different things.

If you found this helpful or have comments / suggestions then please tell me, I'd love to hear what you think and am always looking for better ways to do things.

  • Andrew
    Author
    Andrew Andrew

    This is an excellent tutorial. I was wondering if you knew how to make a button(IBAction) pass a specific URL into a webview. For instance, I have 3 buttons, and I want each button to load a different webpage when the button is pressed. I know how to setup the webview, but I’m not sure how to display it in the “view did load” method. So far I have this.

    @IBAction func loadRadioView(sender: UIButton) {
    let getCurrentURL = NSURL (string: RadioURL)
    let requestCurrentURL = NSURLRequest(URL: getCurrentURL!)
    mainWebView?.loadRequest(requestCurrentURL)
    }

    Any help would be greatly appreciated.

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Hi Andrew, thank you for the kind comments.

      Are these buttons on the same page or do they go to a different view? If they go to a different view with the UIWebView on it then you could send the URL in the segue and load it that way maybe?

      I have a tutorial on sending data in a segue here.

      Peter.