Is Wkwebview Designed as a Replacement of Uiwebview

Is WKWebView designed as a replacement of UIWebView?

Update: UIWebView is now deprecated and Apple is actively discouraging developers from using it.


There are several reasons, including security (out of process model), performance and memory management. Whether Apple would deprecate UIWebView is not something anyone can answer but Apple, however considering the many limitations there currently are (some partially solved in WebKit2 source repository for future iOS WK2 framework inclusion), my educated guess would be that UIWebView is here to stay for different needs. And considering both WebKitLegacy and WebKit2 (now renamed WebKit) frameworks reference the same implementation frameworks (WebCore, JSCore, etc.), it would not require a lot of work to keep UIWebView alive.

iOS - UIWebView replaced with WKWebView, but for Apple it’s still there

Try from terminal in your base project folder

grep -r "UIWebView" .

(Be careful to "dot" at the end of line)

This will print out all SDK's (including Pods) which are currently using UIWebView.

How can we find UIWebView in Project and replace it with WKWebView?

I solved a similar problem as follows:

  1. Search in the workspace UIWebView and replace it with WKWebView

  2. Remove UIWebView in the storyboards and add "WKWebView" instead (do not forget about the connection with the code)

  3. In the terminal, in the project folder, enter the command:

    grep -r "UIWebView" .

    (don't forget the space and the dot at the end of command!) to find links to UIWebView in library files.

  4. Update the libraries with UIWebView, and if it does not help, then delete all libraries that have links to UIWebView.
    (Most libraries with UIWebView have new updates without UIWebView.)

WKWebView vs UIWebView

You can simply create and add a WKWebView via code.

If you want a visual representation for layout purposes in your Storyboard, here is one way to do it.

Add a standard UIView in your view controller in your Storyboard. This will act as a "holder" for your web view. Connect it to an IBOutlet, then in viewDidLoad add an instance of WKWebView as a subview of that "holder" view.

class MyViewController: UIViewController, WKNavigationDelegate {

// standard UIView, added in Storyboard
@IBOutlet weak var webViewHolder: UIView!

// instance of WKWebView
let wkWebView: WKWebView = {
let v = WKWebView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()

override func viewDidLoad() {

super.viewDidLoad()

// add the WKWebView to the "holder" UIView
webViewHolder.addSubview(wkWebView)

// pin to all 4 edges
wkWebView.topAnchor.constraint(equalTo: webViewHolder.topAnchor, constant: 0.0).isActive = true
wkWebView.bottomAnchor.constraint(equalTo: webViewHolder.bottomAnchor, constant: 0.0).isActive = true
wkWebView.leadingAnchor.constraint(equalTo: webViewHolder.leadingAnchor, constant: 0.0).isActive = true
wkWebView.trailingAnchor.constraint(equalTo: webViewHolder.trailingAnchor, constant: 0.0).isActive = true

// load a URL into the WKWebView
if let url = URL(string: "https://google.com") {
wkWebView.load(URLRequest(url: url))
}

// from here on out, use wkWebView just as if you had added it in your storyboard

}

}

Replaced UIWebView with WKWebView, but still same error from Apple

How can I check if the UIWebView is completely removed from the project or not?

Solution is:

  1. Open terminal. Open your project root folder in terminal.
  2. Run Command: grep -r "UIWebView" .
  3. This command will list all the pods that contains “UIWebView”. No either update these pods or remove these pods and ren the step 2 command again. Repeat till all “UIWebView” matches are not removed.


Below are some steps that will guide you to update existing UIWebView to WKWebView.

Import the “WebKit” class to the Controller.

Suppose you are using a UIWebView named “webViewMain”. Then go to your storyboard and simply replace the UIWebView with UIView. Make sure that you have added the same constraints to UIView that were added to UIWebView. Draw @IBOutlet from the new UIView to existing @IBOutlet of UIWebView.
Here you need to change the class of @IBOutlet from UIWebView to UIView because you have replaced the UIWebView with UIView.

Older Code: @IBOutlet weak var webViewMain: UIWebView!
New Code: @IBOutlet weak var webViewMain: UIView!

Then create a new variable to create a new WKWebView.
CODE: var webView : WKWebView!

Add below code where you load request/html in the UIWebView:

// WKWebView
// init and load request in webview.
webView = WKWebView(frame: self.webViewMain.frame)
webView.navigationDelegate = self
self.webView.load(request)
self.webViewMain.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
// Adding constraints from webView(WKWebView) to webViewMain (UIView)
webView.leadingAnchor.constraint(equalTo: webViewMain.leadingAnchor, constant: 0).isActive = true
webView.trailingAnchor.constraint(equalTo: webViewMain.trailingAnchor, constant: 0).isActive = true
webView.topAnchor.constraint(equalTo: webViewMain.topAnchor, constant: 0).isActive = true
webView.bottomAnchor.constraint(equalTo: webViewMain.bottomAnchor, constant: 0).isActive = true
// WKWebView

Till now you have replaced UIWebView with WKWebView .
Now comes the delegate methods.
UIWebView has delegate class: UIWebViewDelegate
WKWebView has delegate class: WKNavigationDelegate

Replace UIWebViewDelegate with WKNavigationDelegate.



Now comes delegate method comparison for UIWebView vs WKWebView:

UIWebView: func webViewDidFinishLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)

UIWebView: func webViewDidStartLoad(_ webView: UIWebView)
WKWebView: func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)

UIWebView: func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool
Here we return true/false to load/cancel the navigation.
WKWebView: func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
Here we returndecisionHandler(.allow)/decisionHandler(.cancel) to load/cancel the navigation.

To Scale aspect fit content of the webView (WKWebView).

var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"
webView.evaluateJavaScript(scriptContent, completionHandler: nil)

To set the height of the webView:

webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
self.constraintWebViewProductDescriptionHeight.constant = height as! CGFloat
})
}
})

Migrate from UIWebview to WKWebview

You only need to change, the UIWebView for WKWebView add import WebKit and change the class name for your Outlet to WKWebView, also change the loadRequest for load

import UIKit
import WebKit

class ViewController: UIViewController {

@IBOutlet weak var webView: WKWebView!

let urlString: String = "https://google.com"

override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: urlString) else { return }
let requestObj = URLRequest(url: url)
webView.load(requestObj)
}

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

}

How change this from UIWebView to WKWebView?

Simply changing

@property (weak, nonatomic) IBOutlet UIWebView *contentWebView;

to

@property (weak, nonatomic) IBOutlet WKWebView *contentWebView;

should work.


If you intend to provide support for both iOS 7 and iOS 8, you'll have to declare two variables and add the following verification:

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


Related Topics



Leave a reply



Submit