How to Migrate to WKWebView?

UiwebviewIos8Wkwebview

Uiwebview Problem Overview


I'm trying to understand how to make use of the new WKWebView in iOS8, can't find much information. I've read:

http://developer.telerik.com/featured/why-ios-8s-wkwebview-is-a-big-deal-for-hybrid-development/ http://nshipster.com/wkwebkit/

But how does this affect existing apps? Will an ordinary UiWebView get the speedup from the nitro java script engine or do we need to make changes? How do we deal with backwards compatibility?

All the code and examples I can find are using swift, will this be mandatory?

Thankful for any help on this matter!

Uiwebview Solutions


Solution 1 - Uiwebview

UIWebView will still continue to work with existing apps. WKWebView is available starting from iOS8, only WKWebView has a Nitro JavaScript engine.

To take advantage of this faster JavaScript engine in older apps you have to make code changes to use WKWebView instead of UIWebView. For iOS7 and older, you have to continue to use UIWebView, so you may have to check for iOS8 and then apply WKWebView methods / delegate methods and fallback to UIWebView methods for iOS7 and older. Also there is no Interface Builder component for WKWebView (yet), so you have to programmatically implement WKWebView.

You can implement WKWebView in Objective-C, here is simple example to initiate a WKWebView:

WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:theConfiguration];
webView.navigationDelegate = self;
NSURL *nsurl=[NSURL URLWithString:@"http://www.apple.com"];
NSURLRequest *nsrequest=[NSURLRequest requestWithURL:nsurl];
[webView loadRequest:nsrequest];
[self.view addSubview:webView];

WKWebView rendering performance is noticeable in WebGL games and something that runs complex JavaScript algorithms, if you are using webview to load a simple html or website, you can continue to use UIWebView.

Here is a test app that can used to open any website using either UIWebView or WKWebView and you can compare performance, and then decide on upgrading your app to use WKWebView: https://itunes.apple.com/app/id928647773?mt=8&at=10ltWQ

enter image description here

Solution 2 - Uiwebview

Here is how I transitioned from UIWebView to WKWebView.

> Note: There is no property like UIWebView that you can drag onto your > storyboard, you have to do it programatically.

Make sure you import WebKit/WebKit.h into your header file.

This is my header file:

#import <WebKit/WebKit.h>

@interface ViewController : UIViewController

@property(strong,nonatomic) WKWebView *webView;
@property (strong, nonatomic) NSString *productURL;

@end

Here is my implementation file:

#import "ViewController.h"

@interface ViewController ()

@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.productURL = @"http://www.URL YOU WANT TO VIEW GOES HERE";

    NSURL *url = [NSURL URLWithString:self.productURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    _webView = [[WKWebView alloc] initWithFrame:self.view.frame];  
    [_webView loadRequest:request];
    _webView.frame = CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    [self.view addSubview:_webView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Solution 3 - Uiwebview

Step : 1 Import webkit in ViewController.swift

import WebKit

Step : 2 Declare variable of webView.

var webView : WKWebView!

Step : 3 Adding Delegate of WKNavigationDelegate

class ViewController: UIViewController , WKNavigationDelegate{

Step : 4 Adding code in ViewDidLoad.

let myBlog = "https://iosdevcenters.blogspot.com/"
let url = NSURL(string: myBlog)
let request = NSURLRequest(URL: url!)

// init and load request in webview.
webView = WKWebView(frame: self.view.frame)
webView.navigationDelegate = self
webView.loadRequest(request)
self.view.addSubview(webView)
self.view.sendSubviewToBack(webView)

Step : 5 Edit the info.plist adding

<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>google.com</key>
<dict>
    <key>NSExceptionAllowsInsecureHTTPLoads</key>
    <true/>
    <key>NSIncludesSubdomains</key>
    <true/>
</dict>
</dict>

Solution 4 - Uiwebview

Swift is not a requirement, everything works fine with Objective-C. UIWebView will continue to be supported, so there is no rush to migrate if you want to take your time. However, it will not get the javascript and scrolling performance enhancements of WKWebView.

For backwards compatibility, I have two properties for my view controller: a UIWebView and a WKWebView. I use the WKWebview only if the class exists:

if ([WKWebView class]) {
    // do new webview stuff
} else {
    // do old webview stuff
}

Whereas I used to have a UIWebViewDelegate, I also made it a WKNavigationDelegate and created the necessary methods.

Solution 5 - Uiwebview

WkWebView is much faster and reliable than UIWebview according to the Apple docs. Here, I posted my WkWebViewController.

import UIKit
import WebKit

class WebPageViewController: UIViewController,UINavigationControllerDelegate,UINavigationBarDelegate,WKNavigationDelegate{

	var webView: WKWebView?
	var webUrl="http://www.nike.com"
	
	override func viewWillAppear(animated: Bool){
		super.viewWillAppear(true)
		navigationController!.navigationBar.hidden = false
		
	}
	override func viewDidLoad()
	{
		/* Create our preferences on how the web page should be loaded */
		let preferences = WKPreferences()
		preferences.javaScriptEnabled = false
		
		/* Create a configuration for our preferences */
		let configuration = WKWebViewConfiguration()
		configuration.preferences = preferences
		
		/* Now instantiate the web view */
		webView = WKWebView(frame: view.bounds, configuration: configuration)
		
		if let theWebView = webView{
			/* Load a web page into our web view */
			let url = NSURL(string: self.webUrl)
			let urlRequest = NSURLRequest(URL: url!)
			theWebView.loadRequest(urlRequest)
			theWebView.navigationDelegate = self
			view.addSubview(theWebView)
			
		}
		

	}
	/* Start the network activity indicator when the web view is loading */
	func webView(webView: WKWebView,didStartProvisionalNavigation navigation: WKNavigation){
			UIApplication.sharedApplication().networkActivityIndicatorVisible = true
	}
	
	/* Stop the network activity indicator when the loading finishes */
	func webView(webView: WKWebView,didFinishNavigation navigation: WKNavigation){
			UIApplication.sharedApplication().networkActivityIndicatorVisible = false
	}
	
	func webView(webView: WKWebView,
		decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse,decisionHandler: ((WKNavigationResponsePolicy) -> Void)){
			//print(navigationResponse.response.MIMEType)
			decisionHandler(.Allow)
			
	}
	override func didReceiveMemoryWarning(){
		super.didReceiveMemoryWarning()
	}

}
 

Solution 6 - Uiwebview

WKWebView using Swift in iOS 8..

The whole ViewController.swift file now looks like this:

import UIKit
import WebKit

class ViewController: UIViewController {
    
    @IBOutlet var containerView : UIView! = nil
    var webView: WKWebView?
                            
    override func loadView() {
        super.loadView()
        
        self.webView = WKWebView()
        self.view = self.webView!
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
       
        var url = NSURL(string:"http://www.kinderas.com/")
        var req = NSURLRequest(URL:url)
        self.webView!.loadRequest(req)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}

Solution 7 - Uiwebview

Use some design patterns, you can mix UIWebView and WKWebView. The key point is to design a unique browser interface. But you should pay more attention to your app's current functionality, for example: if your app using NSURLProtocol to enhance network ability, using WKWebView you have no chance to do the same thing. Because NSURLProtocol only effects the current process, and WKWebView using muliti-process architecture, the networking staff is in a seperate process.

Solution 8 - Uiwebview

You have to use WKWebView, which is available as of iOS8 in Framework 'WebKit' to get the speedup. If you need backwards compatibility, you have to use UIWebView for iOS7 and older.

I set up a little code to provide the UIViewController frame for the new WKWebView. It can be installed via cocoapods. Have a look here:

STKWebKitViewController on github

Solution 9 - Uiwebview

Swift 4

    let webView = WKWebView()   // Set Frame as per requirment, I am leaving it for you
    let url = URL(string: "http://www.google.com")!
    webView.load(URLRequest(url: url))
    view.addSubview(webView)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaniel &#197;kessonView Question on Stackoverflow
Solution 1 - UiwebviewkrisrakView Answer on Stackoverflow
Solution 2 - UiwebviewAliView Answer on Stackoverflow
Solution 3 - UiwebviewKirit ModiView Answer on Stackoverflow
Solution 4 - UiwebviewweiyinView Answer on Stackoverflow
Solution 5 - UiwebviewChetan DobariyaView Answer on Stackoverflow
Solution 6 - UiwebviewPrasathBabuView Answer on Stackoverflow
Solution 7 - UiwebviewProteasView Answer on Stackoverflow
Solution 8 - UiwebviewstkView Answer on Stackoverflow
Solution 9 - UiwebviewMadan guptaView Answer on Stackoverflow