Skip to content

netless-io/NTLBridge-Swift

Repository files navigation

NTLBridge-Swift

Swift Package Manager Platform License

NTLBridge-Swift 是一个强大且轻量级的 JavaScript 桥接库,专为 iOS 和 macOS 应用程序设计。它能够在您的 Swift/Objective-C 代码和 WKWebView 中运行的 JavaScript 之间实现无缝的双向通信,并完全兼容 https://github.com/netless-io/Whiteboard-bridge 规范。

功能特性

  • 双向通信
  • 支持异步与同步
  • 支持JavaScript错误结构化捕获
  • Codable支持
  • 字面量支持

安装

Swift Package Manager

.package(url: "https://github.com/netless-io/NTLBridge-Swift.git", from: "1.0.0")

快速入门

1. 基础设置

import NTLBridge
import WebKit
class ViewController: UIViewController {
    var webView: NTLWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // 创建 web 视图
        let config = WKWebViewConfiguration()
        webView = NTLWebView(frame: view.bounds, configuration: config)
        view.addSubview(webView)
        // 启用调试模式(可选)
        webView.isDebugMode = true
        // 加载 HTML
        if let url = Bundle.main.url(forResource: "index", withExtension:
 "html") {
            webView.loadFileURL(url, allowingReadAccessTo:
url.deletingLastPathComponent())
        }
    }
}

2. 注册原生方法

// 注册简单方法
webView.register(methodName: "getDeviceInfo") { param in
    return [
        "device": UIDevice.current.model,
        "system": UIDevice.current.systemVersion
    ]
}

// 注册类型安全的方法
webView.register(methodName: "getUserData", expecting: String.self) { userId in
    return [
        "id": userId,
        "name": "User \(userId)"
    ]
}

// 注册自定义类型的方法
struct UserData: Codable {
    let id: String
    let name: String
}
webView.register(methodName: "createUser", expecting: UserData.self) { userData in
    return "User created: \(userData.name)"
}

// 注册异步方法
webView.registerAsync(methodName: "fetchData") { param, completion in
    // 模拟网络调用
    DispatchQueue.global().async {
        let result = "数据获取成功"
        completion(.success(.string(result)))
    }
}

// 注册类型安全的异步方法
struct RequestData: Codable {
    let userId: String
    let type: String
}
webView.registerAsync(methodName: "fetchUserData", expecting: RequestData.self) { requestData, completion in
    DispatchQueue.global().async {
        // 模拟异步网络请求
        let userData = ["id": requestData.userId, "name": "User \(requestData.userId)"]
        completion(.success(.dictionary(userData.mapValues { .string($0) })))
    }
}

// 使用字面量语法
webView.register(methodName: "calculate") { param in
    return ["result": 42, "success": true]
}

3. 从原生调用 JavaScript

// 调用 JavaScript 方法
webView.callHandler("showAlert", arguments: ["来自 Swift 的问候!"]) { result in
    switch result {
    case .success(let value):
        print("JS 响应: \(String(describing: value))")
    case .failure(let error):
        print("错误: \(error)")
    }
}

// 使用类型安全的调用方法
struct User: Codable {
    let id: String
    let name: String
}
webView.callTypedHandler("updateUser", arguments: [user], expecting: User.self) { result in
    switch result {
    case .success(let updatedUser):
        print("更新后的用户: \(updatedUser.name)")
    case .failure(let error):
        print("错误: \(error)")
    }
}

// 支持Codable类型
let user = User(id: "123", name: "张三")
webView.callHandler("updateUser", arguments: [user])

// 使用 JSON 字面量调用
webView.callHandler("calculate", arguments: [10, 20, "add"])

Web 集成

使用 @netless/webview-bridge

Web 端使用 @netless/webview-bridge 实现无缝集成(版本需要 >= 0.2.1):

高级功能

1. JSONValue 字面量支持

// 支持所有Swift字面量语法
let stringValue: JSONValue = "Hello"
let numberValue: JSONValue = 42
let boolValue: JSONValue = true
let arrayValue: JSONValue = [1, 2, 3]
let dictValue: JSONValue = ["key": "value"]
let nullValue: JSONValue = nil

// 在桥接调用中使用
webView.register(methodName: "getConfig") { _ in
    return [
        "appName": "MyApp",
        "version": 1.0,
        "features": ["feature1", "feature2"],
        "debug": false
    ]
}

2. 完整的 API 方法

// 取消注册方法
webView.unregister(methodName: "getDeviceInfo")

// 获取已注册的方法列表
let methods = webView.registeredMethods
print("已注册的方法: \(methods)")

// 类型安全的异步注册
struct LoginRequest: Codable {
    let username: String
    let password: String
}
struct LoginResponse: Codable {
    let token: String
    let userId: String
}

webView.registerAsync(methodName: "login", expecting: LoginRequest.self) { request, completion in
    // 处理登录逻辑
    let response = LoginResponse(token: "abc123", userId: request.username)
    completion(.success(.string(response.token)))
}

// 使用 JSON 字符串调用
webView.callHandler("updateConfig", jsonString: "{\"theme\":\"dark\",\"fontSize\":16}")

3. Codable 支持

// 定义Codable类型
struct Config: Codable {
    let apiUrl: String
    let timeout: Int
    let enableCache: Bool
}

// 在桥接中使用
webView.register(methodName: "loadConfig") { _ in
    let config = Config(apiUrl: "https://api.example.com", timeout: 30, enableCache: true)
    return try? JSONValue(codable: config)
}

MIT License - 详见 LICENSE 文件

About

NTLBridge-Swift

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •