### Setup WKWebView Javascript Bridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/errors.md
Call this setup function to initialize the bridge. It takes a callback that is executed once the bridge is ready.
```javascript
setupWKWebViewJavascriptBridge(function(bridge) {
console.log('Bridge ready');
});
```
--------------------------------
### Use Initialized JavaScript Bridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Example of how to use the bridge object after it has been successfully set up.
```javascript
setupWKWebViewJavascriptBridge(function(bridge) {
console.log('Bridge ready!');
// Now you can use bridge.registerHandler, bridge.callHandler
});
```
--------------------------------
### Setup WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/WKWebViewJavascriptBridgeDemo/Demo.html
Initializes the WKWebViewJavascriptBridge. It ensures the bridge is ready before proceeding and handles the callback mechanism for when the bridge becomes available.
```javascript
function setupWKWebViewJavascriptBridge(callback) {
if (window.WKWebViewJavascriptBridge) {
return callback(WKWebViewJavascriptBridge);
}
if (window.WKWVJBCallbacks) {
return window.WKWVJBCallbacks.push(callback);
}
window.WKWVJBCallbacks = [callback];
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}
```
--------------------------------
### Minimal WKWebViewJavascriptBridge Setup
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
This snippet shows the basic initialization of WKWebViewJavascriptBridge within a ViewController. It sets up a WKWebView and then initializes the bridge with it. Load a URL to see it in action.
```swift
import UIKit
import WebKit
import WKWebViewJavascriptBridge
class ViewController: UIViewController {
var webView: WKWebView!
var bridge: WKWebViewJavascriptBridge!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
view.addSubview(webView)
bridge = WKWebViewJavascriptBridge(webView: webView)
if let url = URL(string: "https://example.com") {
webView.load(URLRequest(url: url))
}
}
}
```
--------------------------------
### Setup WKWebViewJavascriptBridge in JavaScript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/README.md
Include this JavaScript function in your web content to set up the bridge. It handles the initial connection and callback registration.
```javascript
function setupWKWebViewJavascriptBridge(callback) {
if (window.WKWebViewJavascriptBridge) { return callback(WKWebViewJavascriptBridge); }
if (window.WKWVJBCallbacks) { return window.WKWVJBCallbacks.push(callback); }
window.WKWVJBCallbacks = [callback];
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}
```
--------------------------------
### Example: Call Native Handler for Current Time
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Shows calling a native handler to get the current server time, using a callback but no explicit data.
```javascript
// Call with just a callback (data is null)
bridge.callHandler('getCurrentTime', function(timeData) {
console.log('Server time:', timeData.timestamp);
});
```
--------------------------------
### Example Message (JavaScript to Native - Response)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Shows an example of a message sent from JavaScript back to native code, typically as a response to a previous native call. It includes the response ID and response data.
```swift
let response: WKWebViewJavascriptBridgeBase.Message = [
"responseID": "native_iOS_cb_1",
"responseData": ["result": "success"]
]
```
--------------------------------
### Full ViewController Integration with WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
A comprehensive example showing how to set up WKWebView, WKWebViewJavascriptBridge, register native handlers, and load HTML content with JavaScript interactions.
```swift
class HybridViewController: UIViewController {
var webView: WKWebView!
var bridge: WKWebViewJavascriptBridge!
var userData: [String: Any]?
override func viewDidLoad() {
super.viewDidLoad()
setupWebView()
setupBridge()
}
private func setupWebView() {
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences.allowsContentJavaScript = true
webView = WKWebView(frame: view.bounds, configuration: config)
view.addSubview(webView)
}
private func setupBridge() {
bridge = WKWebViewJavascriptBridge(webView: webView)
#if DEBUG
bridge.isLogEnable = true
#endif
registerHandlers()
loadWebContent()
}
private func registerHandlers() {
// Get device info
bridge.register(handlerName: "getDeviceInfo") { _, callback in
callback?([
"model": UIDevice.current.model,
"osVersion": UIDevice.current.systemVersion,
"orientation": UIDevice.current.orientation.rawValue
])
}
// Get user data
bridge.register(handlerName: "getUserData") { _, callback in
callback?(self.userData ?? [:])
}
// Update user data
bridge.register(handlerName: "updateUser") { [weak self] params, callback in
guard let self = self, let params = params else {
callback?(["error": "Invalid data"])
return
}
self.userData = params
callback?(["success": true])
}
// Log from JS
bridge.register(handlerName: "log") { params, _ in
if let message = params?["message"] as? String {
print("[JS] \(message)")
}
}
}
private func loadWebContent() {
let htmlString = """
Hybrid App
"""
webView.loadHTMLString(htmlString, baseURL: nil)
}
}
```
--------------------------------
### Example: Call Native Handler for Analytics Logging
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Illustrates calling a native handler to log analytics events, sending data but not expecting a response.
```javascript
// Call with data, no response
bridge.callHandler('logAnalytics', { event: 'page_viewed' });
```
--------------------------------
### Example: Call Native Handler for User Data
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Demonstrates calling a native handler to retrieve user data, including sending specific data and handling the response.
```javascript
// Call with data and callback
bridge.callHandler('getUserData', { id: 123 }, function(userData) {
console.log('User:', userData.name);
});
```
--------------------------------
### Example Swift Dictionary for Serialization
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/message-protocol.md
An example of a Swift dictionary structure that can be serialized into a JSON string for communication.
```swift
let message: [String: Any] = [
"handlerName": "test",
"data": ["key": "value"],
"callbackID": "native_iOS_cb_1"
]
// Produces: {"handlerName":"test","data":{"key":"value"},"callbackID":"native_iOS_cb_1"}
```
--------------------------------
### Example Usage of Callback Type
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Demonstrates how to define and use a callback function when making a bridge call. The callback receives response data from the handler.
```swift
let callback: WKWebViewJavascriptBridgeBase.Callback = { response in
if let dict = response as? [String: Any] {
print("Response:", dict)
}
}
bridge.call(handlerName: "fetchData", callback: callback)
```
--------------------------------
### Example Message (Native to JavaScript)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Illustrates the structure of a message sent from native iOS code to JavaScript, including handler name, data, and an optional callback ID.
```swift
let message: WKWebViewJavascriptBridgeBase.Message = [
"handlerName": "processData",
"data": ["input": "value"],
"callbackID": "native_iOS_cb_1"
]
```
--------------------------------
### Example Usage of WKWebViewJavascriptBridgeBase Callback
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/api-reference/wkwebviewjavascriptbridgebase.md
Demonstrates how to define and use a callback function that conforms to the WKWebViewJavascriptBridgeBase.Callback type alias. This is used to handle responses from JavaScript.
```swift
let callback: WKWebViewJavascriptBridgeBase.Callback = {
response in
print("Received: \(response ?? \"nil\")")
}
```
--------------------------------
### Example Message (JavaScript to Native - Handler Call)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Demonstrates a message originating from JavaScript that invokes a native handler. It includes the handler name, data payload, and a callback ID for potential future responses.
```swift
let callFromJS: WKWebViewJavascriptBridgeBase.Message = [
"handlerName": "getUserData",
"data": ["userId": 123],
"callbackID": "cb_1_1234567890"
]
```
--------------------------------
### Required WKUserContentController Setup
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Configure the WKUserContentController for the bridge. The bridge automatically registers necessary message handlers and uses LeakAvoider.
```swift
let config = WKWebViewConfiguration()
let controller = config.userContentController
// Message handlers are automatically registered by the bridge
// No manual setup needed
let webView = WKWebView(frame: .zero, configuration: config)
```
--------------------------------
### Example Usage of Handler Type
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Illustrates how to define and register a handler to process messages from JavaScript. The handler can optionally send a response back using the provided callback.
```swift
let handler: WKWebViewJavascriptBridgeBase.Handler = { params, callback in
if let message = params?["message"] as? String {
print("Message from JS:", message)
}
callback?(["status": "ok"])
}
bridge.register(handlerName: "logMessage", handler: handler)
```
--------------------------------
### Register Asynchronous JavaScript Handler
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Example of registering a handler that performs an asynchronous operation (like a fetch request) and then calls the response callback.
```javascript
bridge.registerHandler('fetchUserProfile', function(data, responseCallback) {
const userId = data.userId;
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(profile => {
responseCallback(profile);
})
.catch(err => {
responseCallback({ error: err.message });
});
});
```
--------------------------------
### Complete WKWebView Javascript Bridge Initialization and Usage
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
This example demonstrates how to initialize the WKWebView Javascript Bridge and register handlers for native calls, as well as how to call native handlers from JavaScript. Ensure the `iOS_Native_InjectJavascript` message handler is configured on the native side.
```javascript
function setupWKWebViewJavascriptBridge(callback) {
if (window.WKWebViewJavascriptBridge) {
return callback(WKWebViewJavascriptBridge);
}
if (window.WKWVJBCallbacks) {
return window.WKWVJBCallbacks.push(callback);
}
window.WKWVJBCallbacks = [callback];
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}
setupWKWebViewJavascriptBridge(function(bridge) {
// Register handlers that native can call
bridge.registerHandler('displayAlert', function(data, responseCallback) {
alert(data.message);
responseCallback({ dismissed: true });
});
// Call a native handler
bridge.callHandler('getDeviceInfo', null, function(deviceInfo) {
console.log('Device:', deviceInfo.model, deviceInfo.osVersion);
});
});
```
--------------------------------
### Example JavaScript Object for Serialization
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/message-protocol.md
An example of a JavaScript object structure that can be serialized into a JSON string for communication with native code.
```javascript
const message = {
"handlerName": "test",
"data": { "key": "value" },
"callbackID": "cb_1_1704067200000"
};
// Produces: {"handlerName":"test","data":{"key":"value"},"callbackID":"cb_1_1704067200000"}
```
--------------------------------
### Example: Call Native Handler to Trigger UI
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Demonstrates calling a native handler that performs an action on the native side, such as triggering a UI element, without sending data or expecting a response.
```javascript
// Call with no arguments
bridge.callHandler('triggerNativeUI');
```
--------------------------------
### Setup WKWebView Javascript Bridge in HTML
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
This script configures the WKWebViewJavascriptBridge by checking for its existence, managing callbacks, and injecting the bridge into the web view. It's used to establish communication between the web view and the native application.
```html
```
--------------------------------
### Use WKWebViewJavascriptBridge in JavaScript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/README.md
After setup, use the bridge in JavaScript to register handlers that the native side can call and to call native handlers. Ensure setupWKWebViewJavascriptBridge is called first.
```javascript
setupWKWebViewJavascriptBridge(function(bridge) {
/* Initialize your app here */
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
console.log('iOS called testJavascriptHandler with', data)
responseCallback({ 'Javascript Says':'Right back atcha!' })
})
bridge.callHandler('testiOSCallback', {'foo': 'bar'}, function(response) {
console.log('JS got response', response)
})
})
```
--------------------------------
### Complete Round-Trip Message Flow (Native Initiates)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/architecture.md
Visualizes a full communication cycle starting from native code, going to JavaScript, and returning a response. This covers the timing and sequence of events.
```text
Time Native JavaScript
──────────────────────────────────────────────────
0 bridge.call(h, d, cb)
│
1 │ JS ready?
│ ├─ startupQueue = nil
│ └─ dispatch immediately
│
2 │─ Inject JS ─────────────┐
│ │
3 │ ┌────▼──────────────┐
│ │ JS Bridge Loaded │
│ └────┬──────────────┘
│ │
4 │ ┌────▼──────────────┐
│◄────── Flush All │ Dispatch Queued │
│ Startup Queue │ Messages │
│ └────────────────────┘
│
5 ├─ evaluate: _handleMessageFromiOS(json)
│ │
│ ┌────▼──────────────┐
│ │ JS Handler Called │
│ │ Gets data + cb │
│ └────┬──────────────┘
│ │
6 │ cb(responseData)
│ │
7 │ Queue response msg
│ │
8 │ postMessage: FlushQueue
│◄────────────────────────┤
│
9 ├─ fetch queue via JS
│ _fetchQueue()
│ returns JSON array
│◄────────────────────────┤
│
10 ├─ flush(jsonString)
├─ deserialize → [message]
├─ find callback by responseID
│
11 └─ cb(responseData)
Handler receives response
```
--------------------------------
### Example Usage of WKWebViewJavascriptBridgeBase Handler
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/api-reference/wkwebviewjavascriptbridgebase.md
Illustrates how to define and use a handler function that conforms to the WKWebViewJavascriptBridgeBase.Handler type alias. This handler processes incoming messages from JavaScript and can send a response back.
```swift
let handler: WKWebViewJavascriptBridgeBase.Handler = {
params, callback in
print("Handler called with: \(params ?? [:])")
callback?("Response data")
}
```
--------------------------------
### Native Handling Asynchronous Tasks with Callbacks
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Example of a native handler performing an asynchronous task and invoking the callback upon completion. This prevents callback leaks.
```swift
// GOOD: Always clean up if not called
bridge.register(handlerName: "asyncTask") { params, callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
callback?(["result": "done"])
}
}
```
--------------------------------
### Install WKWebViewJavascriptBridge via Swift Package Manager
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/README.md
Use Swift Package Manager in Xcode to add the WKWebViewJavascriptBridge library to your project. Ensure you add it to your target after adding the package dependency.
```swift
// In Xcode: File > Add Package Dependencies
// Enter: https://github.com/Lision/WKWebViewJavascriptBridge.git
// Add to your target
import WKWebViewJavascriptBridge
```
--------------------------------
### Defensive Coding for Handler Parameters
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
This Swift example shows how to safely handle parameters received by a bridge handler. It includes checks for the existence of parameters and type casting for specific values like 'userId' to prevent runtime errors.
```swift
bridge.register(handlerName: "handleData") { params, callback in
guard let params = params else {
callback?([" error": "No parameters"])
return
}
guard let userId = params["userId"] as? Int else {
callback?(["error": "Invalid userId"])
return
}
// Now safe to use userId
print("User ID: \(userId)")
callback?(["status": "ok"])
}
```
--------------------------------
### Example Valid Data Structure
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
This Swift dictionary demonstrates a valid data structure that can be safely transmitted through the bridge, including strings, integers, booleans, arrays, and nested dictionaries.
```swift
let data: [String: Any] = [
"name": "John",
"age": 30,
"active": true,
"scores": [85, 90, 95],
"metadata": ["key": "value"]
]
```
--------------------------------
### Initialize WKWebView and Bridge with Configuration
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
This snippet demonstrates the best practice for initializing a `WKWebView` and `WKWebViewJavascriptBridge` within a `UIViewController`. It includes creating a custom `WKWebViewConfiguration`, enabling development logging in debug builds, registering app-specific handlers, and loading web content.
```swift
class MyViewController: UIViewController {
let webView = WKWebView(frame: .zero, configuration: createWebViewConfig())
var bridge: WKWebViewJavascriptBridge!
static func createWebViewConfig() -> WKWebViewConfiguration {
let config = WKWebViewConfiguration()
config.defaultWebpagePreferences.allowsContentJavaScript = true
config.preferences.javaScriptCanOpenWindowsAutomatically = false
return config
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
// Initialize bridge
bridge = WKWebViewJavascriptBridge(webView: webView)
// Development logging
#if DEBUG
bridge.isLogEnable = true
#endif
// Register app handlers
registerAppHandlers()
// Load content
loadWebContent()
}
private func registerAppHandlers() {
bridge.register(handlerName: "app.getUserData") { params, callback in
guard let userId = params?["id"] as? Int else {
callback?(["error": "Missing id"])
return
}
// Fetch user data
fetchUser(id: userId) { user in
callback?(user)
}
}
}
private func loadWebContent() {
if let url = URL(string: "https://example.com") {
webView.load(URLRequest(url: url))
}
}
}
```
--------------------------------
### Queue Messages Before JavaScript is Ready
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/architecture.md
Implement the Startup Queue pattern to defer sending messages until the JavaScript environment is ready. Messages are appended to a queue if the bridge is not yet active.
```swift
private func queue(message: Message) {
if startupMessageQueue == nil {
dispatch(message: message)
} else {
startupMessageQueue?.append(message)
}
}
```
--------------------------------
### Instantiate WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/README.md
Initialize the WKWebViewJavascriptBridge with a WKWebView instance. This is the first step in setting up the bridge.
```swift
bridge = WKWebViewJavascriptBridge(webView: webView)
```
--------------------------------
### JavaScript: Expected Console Log Messages
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/errors.md
These messages indicate the bridge is operating correctly during setup, handler registration, and successful response handling.
```javascript
// On successful setup
console.log('Bridge ready')
// On handler registration
console.log('Handler registered: handlerName')
// On successful call
console.log('JS got response', response)
```
--------------------------------
### Batch Operations vs. Multiple Calls
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
Demonstrates the difference between making multiple individual calls and a single batch call for adding users. Prefer batch operations for efficiency.
```swift
// AVOID: Multiple calls
for user in users {
bridge.call(handlerName: "addUser", data: user)
}
```
```swift
// PREFER: Single call with batch
bridge.call(handlerName: "addUsers", data: ["users": users])
```
--------------------------------
### Initialize WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/INDEX.md
Initialize the bridge with a WKWebView instance. This is the primary entry point for native integration.
```swift
init(webView: WKWebView)
```
--------------------------------
### setupWKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Initializes the JavaScript bridge. This function must be called before using other bridge functionalities. It ensures the bridge is ready and invokes a callback with the bridge object.
```APIDOC
## setupWKWebViewJavascriptBridge(callback: Function)
### Description
Initializes the JavaScript bridge. This function must be called before using other bridge functionalities. It ensures the bridge is ready and invokes a callback with the bridge object.
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **callback** (Function) - Required - Invoked with the bridge object when ready
### Request Example
```javascript
setupWKWebViewJavascriptBridge(function(bridge) {
console.log('Bridge ready!');
// Now you can use bridge.registerHandler, bridge.callHandler
});
```
### Response
#### Success Response (200)
None (Callback is invoked with the bridge object)
#### Response Example
None
```
--------------------------------
### Invoke or Remove Callbacks in Swift
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/README.md
Always invoke or remove callbacks to prevent memory leaks, especially for asynchronous tasks. This example shows invoking a callback after a delay.
```swift
bridge.register(handlerName: "asyncTask") { _, callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
callback?(["done": true]) // Always call
}
}
```
--------------------------------
### Example of Escaped JSON for JavaScript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/message-protocol.md
Demonstrates the transformation of an original JSON string with a newline character into an escaped version suitable for embedding in JavaScript, ensuring correct parsing.
```plaintext
- Original message: `{"text": "Hello\nWorld"}`
- After escaping: `{"text": "Hello\\nWorld"}`
- Embedded in JS: `WKWebViewJavascriptBridge._handleMessageFromiOS('{"text": "Hello\\nWorld"}')`
- JavaScript parses correctly back to original
```
--------------------------------
### Initialize JavaScript Bridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Call this function before using the bridge. It initializes the bridge and queues callbacks if it's not ready yet.
```javascript
function setupWKWebViewJavascriptBridge(callback) {
if (window.WKWebViewJavascriptBridge) {
return callback(WKWebViewJavascriptBridge);
}
if (window.WKWVJBCallbacks) {
return window.WKWVJBCallbacks.push(callback);
}
window.WKWVJBCallbacks = [callback];
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}
```
--------------------------------
### Default Bridge Initialization
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Initialize the bridge with default settings, which includes disabling logging for production environments.
```swift
// Keep default settings
let bridge = WKWebViewJavascriptBridge(webView: webView)
// isLogEnable defaults to false
```
--------------------------------
### Startup Message Queue
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/api-reference/wkwebviewjavascriptbridgebase.md
Holds messages sent before JavaScript is ready. Outgoing messages are queued here and flushed once JavaScript injection completes. The queue is set to nil after injection.
```swift
var startupMessageQueue: [Message]? = []
```
--------------------------------
### Recommended WKWebView Settings
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Enable JavaScript and disable file access for security. Other preferences like content mode can also be configured.
```swift
let config = WKWebViewConfiguration()
// Allow JavaScript
config.defaultWebpagePreferences.allowsContentJavaScript = true
// Disable file access by default (security)
config.preferences.javaScriptCanOpenWindowsAutomatically = false
// Optional: Configure other settings
config.defaultWebpagePreferences.preferredContentMode = .desktop
let webView = WKWebView(frame: .zero, configuration: config)
```
--------------------------------
### Swift: Prevent Callback Leaks in Bridge Handlers
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/errors.md
Ensure callbacks are always invoked or not registered to prevent memory leaks. This example shows a good practice of always calling the callback and a bad practice of conditional invocation.
```swift
// GOOD: Always invoke callback or don't register one
bridge.register(handlerName: "async") { params, callback in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
callback?(["result": "done"])
}
}
// BAD: Conditional callback invocation
bridge.register(handlerName: "bad") { params, callback in
if someCondition {
callback?(["result": "ok"])
}
// Callback leaked if condition false
}
```
--------------------------------
### Mock Bridge for Testing
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
Implement a mock bridge conforming to a protocol for unit testing. This allows simulating bridge behavior without a real WKWebView.
```swift
protocol BridgeProtocol {
func call(handlerName: String, data: Any?, callback: ((Any?) -> Void)?)
func register(handlerName: String, handler: @escaping (([String: Any]?, ((Any?) -> Void)?) -> Void))
}
extension WKWebViewJavascriptBridge: BridgeProtocol {}
class MockBridge: BridgeProtocol {
var handlers: [String: (([String: Any]?, ((Any?) -> Void)?) -> Void)] = [: ]
func call(handlerName: String, data: Any?, callback: ((Any?) -> Void)?) {
// Mock implementation
}
func register(handlerName: String, handler: @escaping (([String: Any]?, ((Any?) -> Void)?) -> Void)) {
handlers[handlerName] = handler
}
}
```
--------------------------------
### Basic JavaScript Usage for WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/README.md
This snippet shows how to integrate WKWebViewJavascriptBridge in JavaScript. It covers setting up the bridge, registering handlers for native calls, and calling native handlers.
```javascript
function setupWKWebViewJavascriptBridge(callback) {
if (window.WKWebViewJavascriptBridge) return callback(WKWebViewJavascriptBridge);
if (window.WKWVJBCallbacks) return window.WKWVJBCallbacks.push(callback);
window.WKWVJBCallbacks = [callback];
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
}
setupWKWebViewJavascriptBridge(function(bridge) {
// Register a handler that native can call
bridge.registerHandler('jsHandler', function(data, callback) {
console.log('Native called with:', data);
callback({ result: 'done' });
});
// Call a native handler
bridge.callHandler('myHandler', { key: 'value' }, function(response) {
console.log('Native responded:', response);
});
});
```
--------------------------------
### Swift: Prevent Handler Retain Cycles
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/errors.md
Avoid retain cycles by using weak references within handler closures to ensure proper deallocation of self. This example demonstrates a good practice with a weak reference and a bad practice with a strong reference.
```swift
// GOOD: Weak reference
bridge.register(handlerName: "handler") { [weak self] params, callback in
guard let self = self else { return }
// Safe to use self
}
// BAD: Strong reference
bridge.register(handlerName: "handler") { params, callback in
self.property = "value" // Strong capture
}
```
--------------------------------
### Initialize WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/api-reference/wkwebviewjavascriptbridge.md
Initialize the bridge with a WKWebView instance. This must be done after the WKWebView is created but before loading web content. The bridge automatically registers message handlers.
```swift
public init(webView: WKWebView)
```
```swift
import UIKit
import WebKit
import WKWebViewJavascriptBridge
class MyViewController: UIViewController {
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
var bridge: WKWebViewJavascriptBridge!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
bridge = WKWebViewJavascriptBridge(webView: webView)
webView.load(URLRequest(url: URL(string: "https://example.com")!))
}
}
```
--------------------------------
### Project File Organization
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/INDEX.md
Overview of the directory structure for the WKWebView JavaScript Bridge project. This helps in navigating and understanding the location of different modules and documentation files.
```text
output/
├── README.md (Start here!)
├── INDEX.md (This file)
├── api-reference/
│ ├── wkwebviewjavascriptbridge.md (Main API)
│ └── wkwebviewjavascriptbridgebase.md (Internal API)
├── javascript-bridge.md (JS API)
├── types.md (Type definitions)
├── configuration.md (Setup options)
├── usage-patterns.md (Code examples)
├── errors.md (Troubleshooting)
├── architecture.md (Internal design)
└── message-protocol.md (Protocol spec)
```
--------------------------------
### Basic Native Swift Usage for WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/README.md
This snippet demonstrates how to set up WKWebViewJavascriptBridge in native Swift. It includes registering a handler for JavaScript calls and making calls to JavaScript handlers.
```swift
let webView = WKWebView(frame: view.bounds)
view.addSubview(webView)
let bridge = WKWebViewJavascriptBridge(webView: webView)
// Register a handler that JavaScript can call
bridge.register(handlerName: "myHandler") { params, callback in
print("JS called with: \(params)")
callback?(["response": "success"])
}
// Call a JavaScript handler
bridge.call(handlerName: "jsHandler", data: ["key": "value"]) { response in
print("JS responded: \(response)")
}
webView.load(URLRequest(url: URL(string: "https://example.com")!))
```
--------------------------------
### WKWebViewJavascriptBridge Component Architecture
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/architecture.md
Illustrates the high-level structure of WKWebViewJavascriptBridge, showing the interaction between the native application, the bridge's public and internal APIs, WKScriptMessageHandler integration, and the JavaScript runtime within the WKWebView.
```text
┌─────────────────────────────────────────────────────┐
│ Your Native Application (Swift) │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ WKWebViewJavascriptBridge (Public API) │ │
│ │ - init(webView:) │ │
│ │ - register(handlerName:handler:) │ │
│ │ - call(handlerName:data:callback:) │ │
│ │ - remove(handlerName:) │ │
│ │ - reset() │ │
│ │ - isLogEnable │ │
│ └────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────────────────────┐ │
│ │ WKWebViewJavascriptBridgeBase (Internal) │ │
│ │ - Message serialization/deserialization │ │
│ │ - Handler dispatch │ │
│ │ - Callback tracking │ │
│ │ - Startup message queue │ │
│ └────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────────────────────┐ │
│ │ WKScriptMessageHandler Integration │ │
│ │ - iOS_Native_InjectJavascript │ │
│ │ - iOS_Native_FlushMessageQueue │ │
│ └────────────────────────────────────────────────┘ │
└────────────┬──────────────────────────────────────────┘
│
│ WKWebView Integration
│
┌────────────▼──────────────────────────────────────────┐
│ WebView JavaScript Runtime │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ WKWebViewJavascriptBridge (Injected JavaScript) │ │
│ │ - window.WKWebViewJavascriptBridge │ │
│ │ - registerHandler() │ │
│ │ - callHandler() │ │
│ │ - Message queue management │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Your JavaScript Code │ │
│ │ - Handler functions │ │
│ │ - Bridge communication logic │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
--------------------------------
### Native to JavaScript Message Flow
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/architecture.md
Illustrates the steps involved when native code initiates a message to JavaScript. This includes the bridge construction, message queuing, and JavaScript execution.
```text
1. Native Code
├─ bridge.call(handlerName: "foo", data: {...}, callback: {...})
│
2. WKWebViewJavascriptBridge
├─ Delegates to WKWebViewJavascriptBridgeBase.send()
│
3. WKWebViewJavascriptBridgeBase
├─ Constructs Message: ["handlerName": "foo", "data": {...}, "callbackID": "native_iOS_cb_1"]
├─ Calls queue(message:)
│
4. Queue Decision
├─ If JavaScript ready:
│ └─ Calls dispatch(message:)
│ ├─ Serializes message to JSON
│ ├─ Escapes special characters
│ └─ Evaluates JavaScript: WKWebViewJavascriptBridge._handleMessageFromiOS(json)
│
└─ If JavaScript not ready:
└─ Appends to startupMessageQueue (queued until JS ready)
5. JavaScript
├─ _handleMessageFromiOS() receives JSON
├─ Parses and dispatches to registered handler
├─ Handler executes with data and responseCallback
└─ If callback provided, responseCallback queues response back to native
6. Response Flow (Return Path)
├─ JavaScript calls responseCallback(responseData)
├─ Creates message: ["handlerName": "foo", "responseID": "native_iOS_cb_1", "responseData": {...}]
├─ JavaScript queues this message
└─ Next flush sends to native
```
--------------------------------
### WKWebViewJavascriptBridge Initializer
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/api-reference/wkwebviewjavascriptbridge.md
Initializes the WKWebViewJavascriptBridge with a WKWebView instance. This sets up the necessary handlers for bidirectional message passing between native code and JavaScript.
```APIDOC
## `init(webView: WKWebView)`
### Description
Initializes the bridge with a WKWebView instance and sets up internal message handlers.
### Parameters
#### Path Parameters
- **webView** (WKWebView) - Required - The WKWebView instance to bridge communications with. Must not be nil.
### Returns
Initialized WKWebViewJavascriptBridge instance
### Notes
- Must be initialized after WKWebView is created but before loading web content
- Automatically registers message handlers with the webView's userContentController
- The bridge maintains a weak reference to the webView
### Usage Example
```swift
import UIKit
import WebKit
import WKWebViewJavascriptBridge
class MyViewController: UIViewController {
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
var bridge: WKWebViewJavascriptBridge!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
bridge = WKWebViewJavascriptBridge(webView: webView)
webView.load(URLRequest(url: URL(string: "https://example.com")!))
}
}
```
```
--------------------------------
### Check if Bridge is Ready (JavaScript)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Checks for the existence of the main bridge object on the window, indicating that the bridge is ready for use.
```javascript
if (window.WKWebViewJavascriptBridge) {
// Bridge is ready
}
```
--------------------------------
### Response Dispatch Flow
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/message-protocol.md
Explains how responses are dispatched back to the originating callback. This covers creating response messages, queuing them, and invoking the final callback.
```text
callback(responseData)
↓
Create response message: { "responseID": id, "responseData": data }
↓
queue(message)
↓
If ready: dispatch immediately
If not ready: add to startupMessageQueue
↓
Find original callback by ID
↓
Invoke callback with responseData
↓
Remove from pending callbacks
```
--------------------------------
### Safe Initialization with Weak WebView
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
Initializes the bridge safely by holding a weak reference to the WKWebView. This prevents retain cycles. Ensure handlers are set up after bridge initialization.
```swift
class BridgeManager: NSObject {
weak var webView: WKWebView?
var bridge: WKWebViewJavascriptBridge?
func initializeBridge(with webView: WKWebView) {
self.webView = webView
bridge = WKWebViewJavascriptBridge(webView: webView)
setupHandlers()
}
private func setupHandlers() {
guard let bridge = bridge else { return }
// Register handlers
}
}
```
--------------------------------
### Send Array of Objects to JavaScript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
Demonstrates sending an array of dictionaries, where each dictionary represents an object with properties, to a JavaScript handler.
```swift
let items = [
["id": 1, "name": "Item 1", "selected": true],
["id": 2, "name": "Item 2", "selected": false],
["id": 3, "name": "Item 3", "selected": true]
]
bridge.call(handlerName: "setItems", data: ["items": items])
```
--------------------------------
### Native Sending Response to JavaScript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Demonstrates how a native handler can send a JSON-serializable response back to JavaScript using the provided callback function.
```swift
bridge.register(handlerName: "processData") { params, callback in
// Callback is optional
if let cb = callback {
cb(["status": "success", "data": [1, 2, 3]])
}
}
```
--------------------------------
### WKWebViewJavascriptBridge Class Methods
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/MANIFEST.md
This section details the public methods available on the WKWebViewJavascriptBridge class, including initialization, handler registration and calling, and bridge resetting.
```APIDOC
## init(webView:)
### Description
Initializes the WKWebViewJavascriptBridge with a given WKWebView.
### Method
- init
### Parameters
#### Path Parameters
- **webView** (WKWebView) - Required - The WKWebView instance to bridge with.
### Notes
This method is essential for establishing the communication channel between Objective-C/Swift and JavaScript.
### Examples
```swift
let bridge = WKWebViewJavascriptBridge.init(webView: myWebView)
```
## register(handlerName:handler:)
### Description
Registers a handler to be called from JavaScript.
### Method
- register
### Parameters
#### Path Parameters
- **handlerName** (String) - Required - The name of the handler to register.
- **handler** (Handler) - Required - The callback function to execute when the handler is invoked.
### Notes
Handlers allow JavaScript to execute native code.
### Examples
```swift
bridge.register(handlerName: "showAlert") { (data, callback) in
// Handle alert
}
```
## call(handlerName:data:callback:)
### Description
Calls a registered handler from JavaScript, optionally passing data and receiving a callback.
### Method
- call
### Parameters
#### Path Parameters
- **handlerName** (String) - Required - The name of the handler to call.
- **data** (Any) - Optional - Data to send to the handler.
- **callback** (Callback) - Optional - A callback function to receive results from the handler.
### Notes
This method is used to invoke native functionality from the web view.
### Examples
```swift
bridge.call(handlerName: "fetchData", data: nil) { response in
print(response)
}
```
## remove(handlerName:)
### Description
Removes a previously registered handler.
### Method
- remove
### Parameters
#### Path Parameters
- **handlerName** (String) - Required - The name of the handler to remove.
### Notes
Use this to clean up handlers when they are no longer needed.
### Examples
```swift
bridge.remove(handlerName: "oldHandler")
```
## reset()
### Description
Resets the bridge, removing all registered handlers and clearing the message queue.
### Method
- reset
### Notes
Useful for re-initializing the bridge or cleaning up state.
### Examples
```swift
bridge.reset()
```
```
--------------------------------
### Enable Bridge Logging (Native)
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/errors.md
Enable logging on the native side to help diagnose issues with message passing.
```swift
bridge.isLogEnable = true
```
--------------------------------
### Native Request and JavaScript Handler
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/message-protocol.md
Native initiates a request with handler name, data, and a callback ID. JavaScript receives this, registers a handler, processes the data, and prepares a response.
```json
{
"handlerName": "calculateSum",
"data": { "a": 5, "b": 3 },
"callbackID": "native_iOS_cb_1"
}
```
```javascript
bridge.registerHandler('calculateSum', function(data, callback) {
var result = data.a + data.b; // 8
callback({ sum: result });
});
```
--------------------------------
### JavaScript API: window.WKWebViewJavascriptBridge
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/INDEX.md
APIs available in JavaScript for interacting with the native bridge.
```APIDOC
## JavaScript API: window.WKWebViewJavascriptBridge
### Description
APIs available in JavaScript for interacting with the native bridge.
### Initialization
```javascript
setupWKWebViewJavascriptBridge(callback)
```
#### Description
Sets up the JavaScript side of the bridge. The callback is invoked once the bridge is ready.
### Methods
#### `bridge.registerHandler(name, handler)`
##### Description
Registers a JavaScript handler that can be called from native code.
##### Parameters
- **name** (String) - The name of the handler.
- **handler** (Function) - The JavaScript function to execute when the handler is called.
```
```APIDOC
#### `bridge.callHandler(name, [data], [callback])`
##### Description
Calls a native handler from JavaScript.
##### Parameters
- **name** (String) - The name of the native handler to call.
- **data** (Any, optional) - Optional data to send to the native handler.
- **callback** (Function, optional) - Optional callback function to receive a response from the native handler.
```
--------------------------------
### Logging Wrapper for Bridge Calls
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/usage-patterns.md
Create a logging wrapper for bridge calls to automatically log outgoing calls, data, and incoming responses. This simplifies debugging.
```swift
extension WKWebViewJavascriptBridge {
func callWithLogging(handlerName: String, data: Any? = nil, callback: WKWebViewJavascriptBridgeBase.Callback? = nil) {
print("[Bridge] Calling: \(handlerName)")
if let data = data {
print("[Bridge] Data: \(data)")
}
call(handlerName: handlerName, data: data) { response in
print("[Bridge] Response for \(handlerName): \(response ?? "nil")")
callback?(response)
}
}
}
```
--------------------------------
### WKWebViewJavascriptBridge Methods
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/INDEX.md
Provides methods for registering and calling handlers, and managing the bridge.
```APIDOC
## WKWebViewJavascriptBridge Methods
### Description
Provides methods for registering and calling handlers, and managing the bridge.
### Methods
#### `register(handlerName:handler:)`
##### Description
Register a native handler to be called from JavaScript.
##### Parameters
- **handlerName** (String) - The name of the handler to register.
- **handler** (Handler) - The callback function to execute when the handler is invoked.
```
```APIDOC
#### `call(handlerName:data:callback:)`
##### Description
Call a JavaScript handler registered in the web view.
##### Parameters
- **handlerName** (String) - The name of the JavaScript handler to call.
- **data** (Any?) - Optional data payload to send to the JavaScript handler.
- **callback** (Callback?) - Optional callback function to receive a response from the JavaScript handler.
```
```APIDOC
#### `remove(handlerName:)`
##### Description
Unregister a previously registered native handler.
##### Parameters
- **handlerName** (String) - The name of the handler to remove.
```
```APIDOC
#### `reset()`
##### Description
Clears all registered handlers and pending callbacks, resetting the bridge to its initial state.
```
--------------------------------
### Default Implementation for Evaluate Javascript
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/types.md
Provides a default implementation for `evaluateJavascript` that calls the main method with a nil completion handler. This allows for simpler calls when results are not needed.
```swift
extension WKWebViewJavascriptBridgeBaseDelegate {
func evaluateJavascript(javascript: String) {
evaluateJavascript(javascript: javascript, completion: nil)
}
}
```
--------------------------------
### Call Native Handler with Callback, No Data
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/javascript-bridge.md
Call a native handler and provide a callback function, but send no data.
```javascript
bridge.callHandler('handlerName', function(response) { })
```
--------------------------------
### Queue Messages Before JavaScript is Ready
Source: https://github.com/lision/wkwebviewjavascriptbridge/blob/master/_autodocs/configuration.md
Messages sent via `bridge.call` before the JavaScript environment is fully loaded are automatically queued. These messages are then flushed in order once the JavaScript is ready, ensuring no calls are lost. The startup message queue is cleared after flushing.
```swift
// Messages sent before JS ready are queued
bridge.call(handlerName: "handler1", data: data1)
bridge.call(handlerName: "handler2", data: data2)
// When JS loads, all queued messages are flushed
// Messages are processed in order
```