A pure swift interface the JavaScriptCore
C API with support for Encodable
& Decodable
.
Browse the API Documentation.
This permits JSC to be used on platforms where the Objective-C runtime is unavailable (e.g., Linux).
Functions can be accessed (and cached) to be invoked directly with codable arguments:
let ctx = JXContext()
let hypot = ctx["Math"]["hypot"]
assert(hypot.isFunction == true)
let result = hypot.call(withArguments: try [ctx.encode(3), ctx.encode(4)])
assert(result.numberValue == 5)
JXKit supports encoding and decoding Swift types directly into the JXValue
instances, which enables Codable
instances to be passed back and forth to the virtual machine with minimal overhead. Since encoding & decoding doesn't use JSON stringify
& parse
, this can lead to considerable performance improvements when interfacing between Swift & JS.
The above invocation of Math.hypot
can instead be performed by wrapping the arguments in an Encodable
struct, and returning a Decodable
value.
/// An example of invoking `Math.hypot` in a wrapper function that takes an encodable argument and returns a Decodable retult.
struct AB : Encodable { let a, b: Double }
struct C : Decodable { let c: Double }
let ctx = JXContext()
let hypot = try ctx.eval(script: "(function(args) { return { c: Math.hypot(args.a, args.b) }; })")
assert(hypot.isFunction == true)
let result: C = try hypot.call(withArguments: [ctx.encode(AB(a: 3, b: 4))]).toDecodable(ofType: C.self)
assert(result.c == 5)
The JXKit API is a mostly drop-in replacement for the Objective-C JavaScriptCore
framework available on most Apple devices. E.g., the following JavaScriptCore code:
import JavaScriptCore
let ctx = JSContext()
let value: JXValue = ctx.evaluateScript("1+2")
assert(value.doubleValue == 3)
becomes:
import JXKit
let ctx = JXContext()
let value: JXValue = ctx.evaluateScript("1+2")
assert(value.doubleValue == 3)
Note: Requires Swift 5.3+
The Swift Package Manager is a tool for managing the distribution of Swift code.
- Add the following to your
Package.swift
file:
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "MyPackage",
products: [
.library(
name: "MyPackage",
targets: ["MyPackage"]),
],
dependencies: [
.package(name: "JXKit", url: "https://github.com/jectivex/JXKit.git", .upToNextMajor(from: "1.0")),
],
targets: [
.target(
name: "MyPackage",
dependencies: ["JXKit"]),
.testTarget(
name: "MyPackageTests",
dependencies: ["MyPackage"]),
]
)
- Build your project:
$ swift build