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:
Search in the workspace UIWebView and replace it with WKWebView
Remove UIWebView in the storyboards and add "WKWebView" instead (do not forget about the connection with the code)
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.
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:
- Open terminal. Open your project root folder in terminal.
- Run Command: grep -r "UIWebView" .
- 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
Why Must a Protocol Operator Be Implemented as a Global Function
Nearby Bluetooth Devices Using Swift 3.0
How Long Does a Push Notification Sit in Queue Before Being Removed
Alert When New Version of iOS App Is Available
How to Delete an App Which Is Waiting for Upload
How to Sort Nsmutablearray of Date Objects
Hit Detection When Drawing Lines in iOS
Member Operator '%' Must Have at Least One Argument of Type 'Viewcontroller'
Fontawesome Pro and Xamarin.iOS Only One Font Can Be Active
Avassetwriter Avvideoexpectedsourceframeratekey (Frame Rate) Ignored
How to Permanently Allow Usage of Camera on Trusted Websites with iOS - Safari
iOS Permission Alerts - Removing or Suppressing
Error Domain=Nsposixerrordomain Code=100 "Protocol Error"
JSON Parsing Using Nsjsonserialization in iOS
Simple Uitableview in Swift - Unexpectedly Found Nil