WebKit (WKWebView)
-
🔹 What is WebKit?
WebKit is Apple’s web rendering engine used in iOS and macOS to display web content. It powers WKWebView, which allows apps to embed web pages within a native iOS app.
🔹 What is WKWebView
?
✅ WKWebView is the modern web view for iOS.
✅ It replaces UIWebView
(deprecated).
✅ Used for embedding web pages inside apps.
🔹 Basic WKWebView Setup
📌 Load a URL in WKWebView
import WebKit
class ViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
view.addSubview(webView)
if let url = URL(string: "https://www.apple.com") {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
🎯 Key takeaway: WKWebView
is just like Safari inside your app.
🔹 What is WKWebViewConfiguration
?
- It is a configuration object that defines the behavior and settings of a
WKWebView
instance. - It is created before initializing a
WKWebView
, so it can be customized before the web content loads.
🔹 What is WKWebpagePreferences
?
- It controls per-page settings such as JavaScript execution.
🎯 How These Two Work Together
let webConfiguration = WKWebViewConfiguration()
let preferences = WKWebpagePreferences()
preferences.allowsContentJavaScript = false // Disables JavaScript
webConfiguration.defaultWebpagePreferences = preferences // Apply preferences
1️⃣ A WKWebViewConfiguration
is created to hold all WebView settings.
2️⃣ A WKWebpagePreferences
object is created to configure per-page behavior.
3️⃣ JavaScript is disabled using allowsContentJavaScript = false
.
2️⃣ Deep Dive: Advanced Usage
🔹 1. Loading Local HTML Files
Imagine storing a book inside your app and reading it offline.
if let localFile = Bundle.main.url(forResource: "index", withExtension: "html") {
webView.loadFileURL(localFile, allowingReadAccessTo: localFile)
}
📌 Use Case: Offline documentation, app help pages.
🔹 2. JavaScript Communication (Web to Native)
Imagine JavaScript is a customer and Swift is a shopkeeper.
📌 Customer (JS) sends a message to Shopkeeper (Swift).
✅ Step 1: Add a message handler
let contentController = WKUserContentController()
contentController.add(self, name: "jsHandler")
webView.configuration.userContentController = contentController
✅ Step 2: Handle messages in Swift
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("Received message: \(message.body)")
}
}
✅ Step 3: Send message from JavaScript
window.webkit.messageHandlers.jsHandler.postMessage("Hello from JS!");
📌 Use Case: JavaScript-based web apps communicating with the iOS app.
🔹 3. Injecting JavaScript (Native to Web)
Imagine Swift is sending a command to JavaScript inside WKWebView.
webView.evaluateJavaScript("document.body.style.backgroundColor = 'red'") { result, error in
print("JavaScript executed")
}
📌 Use Case: Change webpage content from Swift.
🔹 4. Blocking Requests (Ad Blocker)
Imagine having a firewall that blocks ads.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url, url.absoluteString.contains("ads.com") {
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
📌 Use Case: Blocking unwanted content.
🔹 5. Debugging WKWebView
✅ Enable Safari Developer Tools:
Go to Settings > Safari > Advanced > Web Inspector
✅ Use WKWebView
’s Console Logs in Xcode:
webView.evaluateJavaScript("console.log('Hello from JS')")
3️⃣ Quick Revision Tips 🚀
📌 1. Use a Cheat Sheet:
Memorize WebKit concepts using flashcards.
📌 2. Visualize as a Smart House 🏠
- WKWebView → A window displaying web content
- WKScriptMessageHandler → Mailbox (JavaScript sends messages)
- evaluateJavaScript() → Intercom system (Swift sends commands)
📌 3. Practice Small Code Snippets
- Load a local HTML
- Inject JavaScript
- Block ads
Questions
- What is WebKit, and how is it used in iOS development?
- What is
WKWebView
, and how is it different fromUIWebView
? - How do you load a local HTML file into a
WKWebView
? - What are
WKWebViewConfiguration
andWKPreferences
used for? - How do you enable JavaScript in
WKWebView
? - How do you inject JavaScript code into a webpage from a native iOS app?
- What is
WKScriptMessageHandler
, and how does it help communicate between JavaScript and Swift? - How do you handle navigation actions (e.g., opening links) inside a
WKWebView
? - How can you block or modify network requests in
WKWebView
? - What are
WKUserScript
andWKContentWorld
, and how do they enhance security? - How do you handle cookies and session management in
WKWebView
- How do you debug issues in
WKWebView
, such as performance bottlenecks or JavaScript errors? - How to transfer data web to app and vice-versa
1. What is WebKit, and how is it used in iOS development?
✅ Answer: WebKit is Apple’s web rendering engine used in iOS and macOS to display web content. It powers WKWebView, which allows apps to embed web pages within a native iOS app.
2. What is WKWebView
, and how is it different from UIWebView
?
✅ Answer:
UIWebView
(Deprecated) → Slow, outdated, limited JavaScript support.WKWebView
→ Faster, supports multi-process architecture, better JavaScript integration.
🔹 Example: Adding WKWebView
to a ViewController
import WebKit
class ViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
view.addSubview(webView)
webView.load(URLRequest(url: URL(string: "https://www.apple.com")!))
}
}
3. How do you load a local HTML file into a WKWebView
?
✅ Answer: You can load an HTML file from the app bundle.
🔹 Example:
if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
4. What are WKWebViewConfiguration
and WKPreferences
used for?
✅ Answer:
WKWebViewConfiguration
→ Configures web settings like user scripts and preferences.WKPreferences
→ Controls JavaScript and content settings.
🔹 Example:
let config = WKWebViewConfiguration()
config.preferences.javaScriptEnabled = true // Deprecated, use below:
config.defaultWebpagePreferences.allowsContentJavaScript = true
let webView = WKWebView(frame: .zero, configuration: config)
5. How do you enable JavaScript in WKWebView
?
✅ Answer: Use allowsContentJavaScript
in WKWebpagePreferences
.
🔹 Example:
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences.allowsContentJavaScript = true
webView = WKWebView(frame: .zero, configuration: config)
6. How do you inject JavaScript code into a webpage from a native iOS app?
✅ Answer: Use evaluateJavaScript(_:)
to run JavaScript inside a WKWebView
.
🔹 Example:
webView.evaluateJavaScript("document.body.style.backgroundColor = 'lightgray'") { result, error in
if let error = error {
print("JavaScript Error: \(error)")
} else {
print("JavaScript executed successfully")
}
}
7. What is WKScriptMessageHandler
, and how does it help communicate between JavaScript and Swift?
✅ Answer: WKScriptMessageHandler
allows JavaScript to send messages to native Swift code.
🔹 Example: (JS to Swift Communication)
Step 1: Add Message Handler in Swift
class ViewController: UIViewController, WKScriptMessageHandler {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "messageHandler")
webView = WKWebView(frame: view.bounds, configuration: config)
view.addSubview(webView)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("Received message from JavaScript: \(message.body)")
}
}
Step 2: Send Message from JavaScript (Inside Web Page)
window.webkit.messageHandlers.messageHandler.postMessage("Hello from JavaScript!");
8. How do you handle navigation actions (e.g., opening links) inside a WKWebView
?
✅ Answer:
Use WKNavigationDelegate
to control navigation behavior.
🔹 Example:
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
webView.navigationDelegate = self
view.addSubview(webView)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.request.url?.host == "restricted.com" {
decisionHandler(.cancel) // Block navigation
} else {
decisionHandler(.allow)
}
}
}
🏠 WebKit = A Smart Home
Think of WebKit as a modern smart house that:
✅ Displays web content (like walls displaying paintings).
✅ Communicates with its surroundings (JavaScript, APIs).
✅ Controls security (blocking ads, managing cookies).
13. How to transfer data web to app and vice-versa
Web to app
We have to use userContentController property in the WKWebViewConfiguration And also enable allowsContentJavaScript under the WKWebpagePreferences
And have a delegate method WKScriptMessageHandler to communicate them.
import WebKit
class ViewController: UIViewController {
@IBOutlet weak var txtField: UITextField!
@IBOutlet weak var webView: WKWebView!
private let connectWebToApp = "connectWebToApp"
override func viewDidLoad() {
super.viewDidLoad()
// ✅ Step 1: Create WKWebViewConfiguration
let webConfiguration = WKWebViewConfiguration()
let preferences = WKWebpagePreferences()
preferences.allowsContentJavaScript = true
webConfiguration.defaultWebpagePreferences = preferences
// ✅ Step 2: Create WKWebView with the Configuration
webView2 = WKWebView(frame: webView.bounds, configuration: webConfiguration)
webView.addSubview(webView2)
// ✅ Step 4: Load Local HTML File
if let url = Bundle.main.url(forResource: "sampleweb", withExtension: "html") {
webView2.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
// ✅ Step 5: Add JavaScript Message Handler (It won't work because JS is disabled)
webView2.configuration.userContentController.add(self, name: "messageHandle")
}
@IBAction func btnAction(_ sender: Any) {
guard let data = txtField.text, !data.isEmpty else { return }
webView.evaluateJavaScript("document.getElementById('messageInput').value='\(data)'")
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == connectWebToApp {
txtField.text = message.body as? String
}
}
}