What is BridgeKit?
BridgeKit is a lightweight Swift library designed to simplify communication between your native iOS app and JavaScript code running within a WKWebView
. It provides a clean and intuitive API for sending and receiving messages, enabling seamless interaction between your native and web content.
Why use BridgeKit?
- Simplified Message Handling: BridgeKit abstracts away the complexities of
WKWebView
communication, providing a streamlined approach to sending and receiving messages. - Flexible Data Exchange: Send and receive complex data structures (using
Codable
objects) between your app and the webview. - Improved Maintainability: Separate message handling logic from your view code for better organization and easier maintenance.
Installation:
BridgeKit is available through CocoaPods. To install it, simply add the following line to your Podfile
:
pod 'BridgeKit'
Then, run pod install or pod update in your terminal.
Usage:
-
Import: Import BridgeKit in your view controller:
import BridgeKit
-
Initialize BridgeKit and Configure WKWebView: In your view controller (typically in
viewDidLoad()
), create aWKWebView
, configure itsWKUserContentController
, and initialize an instance ofBridgeKitCore
:- Import necessary modules and conform to WKScriptMessageHandler:
import UIKit import WebKit import BridgeKit class ViewController: UIViewController, WKScriptMessageHandler {
- Configure the WKWebView and initialize BridgeKitCore:
let contentController = WKUserContentController() contentController.add(self, name: "bridgekit") // Important: Must match JS name let config = WKWebViewConfiguration() config.userContentController = contentController webView = WKWebView(frame: .zero, configuration: config) // Give config to your webview bridge = BridgeKitCore(webView: webView) // Inform BridgeKit about webview
-
Register Message Handlers (Swift): Define message handlers in your Swift code to respond to messages from JavaScript. Use structs conforming to the
Topic
protocol to define message topics, andCodable
structs to define the data being sent. It's crucial to match the data structure with the one from js:private func registerHandlers() { // Handle "myTopic" message with string data struct ResponseData: Codable { let receivedText: String } struct ResponseTopic: Topic { let name: String = "myTopic" } bridge.registerMessageHandler(for: ResponseTopic()) { (data: ResponseData, bridge) in print("Received response from web: \(data.receivedText)") } }
-
Send Messages from Swift: Use
bridge.postMessage
to send messages to your JavaScript code. Provide the data (as aCodable
struct) and the topic (as a struct conforming to theTopic
protocol):@objc private func sendTextToWeb() { struct TextData: Codable { let text: String } struct TextTopic: Topic { let name: String = "textFromNative" } bridge.postMessage(data: TextData(text: text), to: TextTopic()) { response in switch response { case .success: print("Text sent to web successfully") case .failure(let error): print("Error sending text to web: \(error)") } } }
-
JavaScript Code (index.html): In your web page, use
window.webkit.messageHandlers.bridgekit.postMessage
to send messages to Swift. Thetopic
and the structure of thedata
object must match the SwiftTopic
andCodable
structs:<!DOCTYPE html> <html> <head> <title>BridgeKit Example</title> <style> body { font-size: 20px; padding: 20px;} button { font-size: 20px; padding: 10px 20px;} #receivedText { font-size: 30px; color: red; text-align: center; margin-top: 20px; font-weight: bold; padding: 10px; border: 2px solid red; } #responseFromNative { margin-top: 10px; } </style> </head> <body> <div id="receivedText"></div> <button onclick="showAlert()">Show Native Alert</button><br><br> <input type="text" id="webInput" placeholder="Enter text here"><br><br> <button onclick="sendMessage()">Send Message to Native</button> <div id="responseFromNative"></div> <script> function sendMessage() { const message = { receivedText: "Hello from JavaScript!" }; // Match Swift struct window.webkit.messageHandlers.bridgekit.postMessage({ topic: "myTopic", data: message }); // Match Swift Topic name } function showAlert() { window.webkit.messageHandlers.bridgekit.postMessage({ topic: "showAlert", data: {} }); // Empty data for alert } window.addEventListener('bridgekit', function(event) { if (event.detail && event.detail.topic === "textFromNative") { const receivedText = event.detail.data.text; document.getElementById('receivedText').innerText = "Hello " + receivedText; } if (event.detail && event.detail.topic === "myTopicResponse") { document.getElementById('responseFromNative').innerText = event.detail.data.response; } }); </script> </body> </html>
For more info please inspect example code.
BridgeKit empowers you to seamlessly bridge the gap between your native app and webview content. With its intuitive API and robust features, it streamlines message handling, simplifies data exchange, and ultimately enhances your app's development experience.
Ayberk Mogol, [email protected]
BridgeKit is available under the MIT license. See the LICENSE file for more info.