SwiftyJSCore 封装了 JavaScriptCore 框架,并提供了一种从 Swift 调用 JavaScript 函数的便捷方式。
SwiftyJSCore 支持:
Codable
类型注意
如果您的应用程序以 iOS 为目标,并且性能对您很重要,请考虑使用 WKWebView。WKWebView 在一个单独的进程中运行,没有安全问题,并使用 JIT 编译器,与 JavaScriptCore 相比,JS 速度明显更快。
SwiftyJSCore 的 API 是并发的,将函数调用和 Promise 抽象为相同的异步 API。
JavaScript
var testString = () => {
return "Foobar";
}
var testAsync = async (arg) => {
return new Promise(resolve => resolve({ "id": arg.id, "name": "Test" }));
}
var testException = async () => {
throw new TypeError("TestError");
}
Swift
let interpreter = try await JSInterpreter()
try await interpreter.evaluateFile(url: jsURL)
try await interpreter.eval("console.log(\"8+13=\", 8+13)")
try await interpreter.setObject(13, forKey: "thirteen")
let sum: Int = try await interpreter.eval("thirteen+8")
assert(sum == 21)
let string: String = try await interpreter.call(function: "testString")
assert(string == "Foobar")
您可以传递 Codable
实体和典型的 JavaScriptCore @objc/NSObject 类作为函数参数。返回值映射到 Swift 原始类型或 Codable
类型。
struct TestEntity: Codable {
let id: Int
let name: String
}
let entity: TestEntity = try await interpreter.call(
function: "testAsync",
arguments: [TestEntity(id: 123, name: "Foobar")])
assert(entity.id == 123 && entity.name == "Test")
do {
let _: Int = try await interpreter.call(function: "testException")
} catch JSError.exception(let name, let message) {
assert(name, "TypeError")
assert(message, "TestError")
}
在您的 JSExport 类中使用 wrapAsyncInJSPromise
将 Swift 异步函数导出到 JavaScript。
查看单元测试以获取使用 SwiftData 的示例。
JS
var fetchPostsForUser = async (id, db) => {
const user = await db.fetchUser(id);
return user.posts;
};
Swift
@objc protocol JSDatabaseAPIProtocol: JSExport {
@objc func fetchUser(_ id: Int) -> JSValue
}
class JSDatabaseAPI: NSObject, JSDatabaseAPIProtocol {
let db = DatabaseAPI()
@objc func fetchUser(_ id: Int) -> JSValue {
return wrapAsyncInJSPromise {
return try await self.db.fetchUser(id: id)
}
}
}