[2020/04/01 Up] [Swift/ObjC] How to replace UIWebView with WKWebView

According to post in Developer News And Updates on December 23, 2019, UIWebView class was deprecated and apps using it will be rejected. I wrote this change in post below.

RelatedPost

There are 3 classes to embed the web browser into the iOS app. UIWebView class WKWebView class SFSafariViewCo[…]

We should use WKWebView or SFSafariViewController instead of UIWebView. This post says how to replace UIWebView with WKWebView.

Loading Pages

Load from URL

This code load the web page from URL with UIWebView.

// Swift
// with UIWebView
func load(url: URL) {
 let request = URLRequest(url: url)
 uiWebView.loadRequest(request)
}
// Objective-C
// with UIWebView
- (void)loadWithURL:(NSURL *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.uiWebView loadRequest:request];
}

The code to load from URL with WKWebView is looking like same.

// Swift
// with WKWebView
func load(url: URL) {
    let request = URLRequest(url: url)
    wkWebView.load(request)
}
// Objective-C
// with WKWebView
#import <WebKit/WebKit.h>

- (void)loadWithURL:(NSURL *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.wkWebView loadRequest:request];
}

Load from the local HTML

This code load the local HTML data with UIWebView. The HTML is a string.

// Swift
uiWebView.loadHTMLString(html, baseURL: baseURL)
// Objective-C
[self.uiWebView loadHTMLString:html
                       baseURL:baseURL];

The code is using WKWebView is below. It is very similar with above.

// Swift
_ = wkWebView.loadHTMLString(html, baseURL: baseURL)
// Objective-C
[self.wkWebView loadHTMLString:html
                       baseURL:baseURL]

Execute JavaScript

This code executes the JavaScript with UIWebView.

// Swift
let result = uiWebView.stringByEvaluatingJavaScript(from: script)
// Objective-C
id result = [self.uiWebView stringByEvaluatingJavaScriptFromString:script];

The code is using WKWebView is below.

// Swift
wkWebView.evaluateJavaScript(script) { (result, error) in

}
// Objective-C版
NSString *script = @"document.title";
[self.wkWebView evaluateJavaScript:script completionHandler:^(id _Nullable result, NSError * _Nullable error) {

}];

UIWebView executes the JavaScript synchronously, the method returns after execution was completed.

WKWebView executes the JavaScript asynchronously, the method return immediately. The execution is completed, the completion block will be performed. You can execute other JavaScript in the completion block.

Perform the operation before and after loading pages

If you want do anything just before or after the page is loading, you need to implement the class adopts to the UIWebViewDelegate protocol.

// Swift
import UIKit

class ViewController: UIViewController, UIWebViewDelegate {
    
    @IBOutlet var uiWebView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()        
        uiWebView.delegate = self
        
        load(url: URL(string: "http://www.example.com")!)
    }

    func load(url: URL) {
        let request = URLRequest(url: url)
        uiWebView.loadRequest(request)
    }
    
    /// Perform just before loading page
    func webViewDidStartLoad(_ webView: UIWebView) {
        print("Start Loading Page")
    }
    
    /// Perform just after loading page
    func webViewDidFinishLoad(_ webView: UIWebView) {
        print("Finish Loading Page")
    }
    
    /// Perform when any errors are encounted
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        print("Failed Loading Page: \(error)")
    }
}
// Objective-C
#import "ViewController.h"

@interface ViewController () <UIWebViewDelegate>

@end

@implementation ViewController
@synthesize uiWebView = _uiWebView;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.uiWebView.delegate = self;
    
    [self loadWithURL:[NSURL URLWithString:@"https://www.example.com"]];
}

- (void)loadWithURL:(NSURL *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.uiWebView loadRequest:request];
}

/// Perform just before loading page
- (void)webViewDidStartLoad:(UIWebView *)webView {
    NSLog(@"Start Loading Page");
}

/// Perform just after loading page
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSLog(@"Finish Loading Page");
}

/// Perform when any errors are encountered
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    NSLog(@"Failed Loading Page: %@", error.localizedDescription);
}

@end

With WKWebView, you need to implement the class adopts WKNavigationDelegate protocol.

WKNavigationDelegate protocol has more methods variations. For example, it is divided into 2 methods that is called just before loading page, preparing and contents. If the specified URL is not reachable, webView(_:didStartProvisisionalNavigation:) method will be called but webView(_:didCommit:) will not.

// Swift
import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    
    @IBOutlet var wkWebView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        wkWebView.navigationDelegate = self
        load(url: URL(string: "https://www.example.com/")!)
    }

    func load(url: URL) {
        let request = URLRequest(url: url)
        wkWebView.load(request)
    }
    
    /// Perform just before loading page
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Start Provisional Navigation")
    }
    
    /// Perform just before loading contents of page
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("Did Commit")
    }
    
    /// Perform just after loading page
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Did Finish")
    }
    
    /// Perform when any errors are encountered
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        print("Did Fail Provisional Navigation")
    }
}
// Objective-C
#import "ViewController.h"

@interface ViewController () <WKNavigationDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.wkWebView.navigationDelegate = self;
    [self loadWithURL:[NSURL URLWithString:@"https://www.example.com"]];
}

- (void)loadWithURL:(NSURL *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.wkWebView loadRequest:request];
}

/// Perform just before loading page
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"Start Provisional Navigation");
}

/// Perform just before loading contents of page - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { NSLog(@"Did Commit"); } /// Perform just after loading page - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"Did Finish"); } /// Perform when any errors are encountered - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"Did Fail Provisional Navigation"); } @end

Conclusion

WKWebView has more rich functionality and more delegate methods than UIWebView. It seems that WKWebView is more flexible.

Related Posts

WKWebViewに関連するその他の記事です。

現役のプログラマーが書くプログラミング情報

このブログ用に作っているサンプルアプリで、WKWebViewを使っているものがあります。先日、Xcodeを11.4にアッ…

現役のプログラマーが書くプログラミング情報

WKWebViewで認証されたページにアクセスしたいときは、確認証方法に合わせた処理が必要です。この記事ではHTTPのB…

Author Profile

Avatar
Akira HayashiA professional developer specializing in macOS Apps, iOS Apps, SDKs and middleware development.
Representative of RK Kaihatsu. I am a professional developer specializing in macOS Apps, iOS Apps, SDKs and middleware development. I often use ObjC, Swift and C++. Based on development experience, I provide e-learning contents, technical books and technical guidance. I am also a technical seminar instructor, in-house training instructor, and administrative / local goverment staff training instructor.
Get the Latest News !

App DeveloperLatest 8 Posts

>Programming Tips From Software Engineer

Programming Tips From Software Engineer

Technical News, Documents and Tips.

CTR IMG