What is WKWebView?
WKWebView
is a powerful web rendering engine introduced in iOS 8 as part of the WebKit framework. It allows iOS apps to display web content efficiently while offering better performance and security than the deprecated UIWebView
.
1. Key Features of WKWebView
✅ Faster performance than UIWebView
✅ Supports JavaScript execution
✅ Offers enhanced security with sandboxing
✅ Allows communication between native Swift code and JavaScript
✅ Provides fine-grained control over web content
2. Adding WKWebView in Storyboard
- Drag & Drop a
WKWebView
from the Object Library. - Set constraints to position it properly within the view.
- Create an
IBOutlet
for the WebView in the ViewController. - Load a URL or HTML content programmatically.
3. Implementing WKWebView Programmatically
3.1 Basic Setup
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Initialize WKWebView
webView = WKWebView(frame: view.bounds)
webView.navigationDelegate = self
view.addSubview(webView)
// Load a URL
if let url = URL(string: "https://www.apple.com") {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
✅ This creates a simple WebView that loads Apple’s website.
4. Loading Different Types of Web Content
4.1 Load a URL
let url = URL(string: "https://www.example.com")!
webView.load(URLRequest(url: url))
4.2 Load Local HTML File
if let localHTMLPath = Bundle.main.path(forResource: "index", ofType: "html") {
let localURL = URL(fileURLWithPath: localHTMLPath)
webView.loadFileURL(localURL, allowingReadAccessTo: localURL)
}
4.3 Load HTML String
let htmlString = "<html><body><h1>Hello, WKWebView!</h1></body></html>"
webView.loadHTMLString(htmlString, baseURL: nil)
5. Handling Web Navigation with WKNavigationDelegate
To monitor navigation events, conform to the WKNavigationDelegate
protocol.
5.1 Detect Page Load Start & End
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Page is loading...")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Page loaded successfully!")
}
5.2 Handle Page Load Errors
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("Failed to load page: \(error.localizedDescription)")
}
6. Enabling JavaScript Execution
By default, WKWebView
supports JavaScript, but additional configurations might be needed.
let webConfig = WKWebViewConfiguration()
webConfig.preferences.javaScriptEnabled = true
let webView = WKWebView(frame: .zero, configuration: webConfig)
7. Communicating Between Swift & JavaScript
7.1 Inject JavaScript into WebPage
webView.evaluateJavaScript("document.body.style.backgroundColor = 'lightgray'") { (result, error) in
if let error = error {
print("JavaScript Error: \(error.localizedDescription)")
}
}
7.2 Send Data from JavaScript to Swift
1️⃣ Add a JavaScript message handler in Swift:
class ViewController: UIViewController, WKScriptMessageHandler {
override func viewDidLoad() {
let contentController = webView.configuration.userContentController
contentController.add(self, name: "messageHandler")
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("Message from JavaScript: \(message.body)")
}
}
2️⃣ Call the message handler from JavaScript:
window.webkit.messageHandlers.messageHandler.postMessage("Hello from JavaScript!");
✅ This enables two-way communication between Swift and JavaScript.
8. Adding Navigation Controls
8.1 Adding a Toolbar with Back & Forward Buttons
let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(goBack))
let forwardButton = UIBarButtonItem(title: "Forward", style: .plain, target: self, action: #selector(goForward))
@objc func goBack() {
if webView.canGoBack {
webView.goBack()
}
}
@objc func goForward() {
if webView.canGoForward {
webView.goForward()
}
}
9. Handling Links Inside WebView
To control how URLs open, implement WKNavigationDelegate
.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url, url.absoluteString.contains("external-site.com") {
UIApplication.shared.open(url) // Open in Safari
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
✅ This ensures external links open in Safari while keeping internal navigation inside WKWebView
.
10. Caching & Performance Optimization
10.1 Enabling Cache for Faster Loading
let cachePolicy = URLRequest.CachePolicy.returnCacheDataElseLoad
let request = URLRequest(url: URL(string: "https://example.com")!, cachePolicy: cachePolicy, timeoutInterval: 10)
webView.load(request)
10.2 Clearing WebView Cache
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
records.forEach { dataStore.removeData(ofTypes: $0.dataTypes, for: [$0], completionHandler: {}) }
}
✅ This prevents excessive data storage and ensures fresh content loading.
11. Common Issues & Fixes
❌ Issue: WebView Not Loading URL
✅ Fix: Ensure the URL is valid and App Transport Security (ATS)
allows non-HTTPS URLs.
Add this to Info.plist
to allow HTTP URLs:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
❌ Issue: JavaScript Not Running
✅ Fix: Enable JavaScript in WKWebViewConfiguration
.
12. Conclusion
✔️ WKWebView
is the recommended way to embed web content in iOS apps.
✔️ Offers faster performance, better security, and full JavaScript support.
✔️ Provides customization options like navigation control, JavaScript execution, and message passing.
✔️ Supports modern web technologies like HTML5, CSS, and JavaScript frameworks.
Would you like a specific WKWebView
feature implementation in your project? 🚀