JSBridge
为 Swift 使用中将您的 JavaScript 库桥接
安装
SwiftPM
dependencies: [
.package(url: "https://github.com/LinusU/JSBridge", from: "1.0.0"),
]
Carthage
github "LinusU/JSBridge" ~> 1.0.0
用法
foobar.js
window.Foobar = {
add (a, b) {
return a + b
},
greet (name) {
return `Hello, ${name}!`
},
async fetch (url) {
const response = await fetch(url)
const body = await response.text()
return { status: response.status, body }
}
}
Foobar.swift
struct FetchResponse: Decodable {
let status: Int
let body: String
}
class Foobar {
static internal let bridge: JSBridge = {
let libraryPath = Bundle.main.path(forResource: "foobar", ofType: "js")!
let libraryCode = try! String(contentsOfFile: libraryPath)
return JSBridge(libraryCode: libraryCode)
}()
static func add(_ lhs: Int, _ rhs: Int) -> Promise<Int> {
return Foobar.bridge.call(function: "Foobar.add", withArgs: (lhs, rhs)) as Promise<Int>
}
static func greet(name: String) -> Promise<String> {
return Foobar.bridge.call(function: "Foobar.greet", withArg: name) as Promise<String>
}
static func fetch(url: URL) -> Promise<FetchResponse> {
return Foobar.bridge.call(function: "Foobar.fetch", withArg: url) as Promise<FetchResponse>
}
}
API
JSBridge(libraryCode: String)
创建一个新的 JSBridge
实例,带有提供的库源代码。
libraryCode
应该是一个字符串形式的JavaScript,它将一个或多个函数附加到 window
对象。然后可以使用 call
方法调用这些函数。
call(function: String) -> Promise
调用一个无参数的函数,忽略返回值。当函数运行完成后,返回的promise将会解决。
call<Result: Decodable>(function: String) -> Promise<Result>
调用一个无参数的函数。返回的promise将以函数的返回值解决。
call<A: Encodable>(function: String, withArg: A) -> Promise
调用一个带有单个参数的函数,忽略返回值。函数完成后,返回的promise将会解决。
call<Result: Decodable, A: Encodable>(function: String, withArg: A) -> Promise<Result>
调用一个带有单个参数的函数。返回的promise将以函数的返回值解决。
call<A: 可编码, B: 可编码, ...>(function: 字符串, withArgs: (A, B, ...)) -> Promise
调用带多个参数的函数,忽略返回值。返回的promise将在函数完成运行后解决。
call<Result: 可解码, A: 可编码, B: 可编码, ...>(function: 字符串, withArgs: (A, B, ...)) -> Promise
调用带多个参数的函数。返回的promise将使用函数的返回值解决。
iOS
为了能够在iOS上使用JSBridge,您需要为JSBridge提供一个视图层次结构的钩子。否则,WKWebView
将被操作系统挂起,并且您的promise永远不会解决。
这可以通过在使用任何JSBridge
实例之前使用setGlobalUIHook
函数来实现。
应用
// Can be called from anywhere, e.g. your AppDelegate
JSBridge.setGlobalUIHook(window: UIApplication.shared.windows.first)
应用扩展
// From within your root view controller
JSBridge.setGlobalUIHook(viewController: self)
黑客技术
Xcode项目是使用XcodeGen从project.yml
自动生成的。它仅因为Carthage需要而被提交,请不要手动编辑它。
$ mint run yonaskolb/xcodegen
💾 Saved project to JSBridge.xcodeproj