JavaScriptCore

CocoaHeadsSKG

Dimitri James Tsiflitzis

Overview

The JavaScriptCore Framework provides the ability to evaluate JavaScript programs from within Swift, Objective-C, C-based apps & vice versa. And inter operably.

JavaScriptCore

  • Create and call JavaScript functions from Swift (and Objective-C & C).
  • Catch JavaScript exceptions.
  • Call Swift (and Objective-C & C) from JavaScript.
  • Sneak preview: Execute JavaScript inside a WKWebView (not UIWebview)

JSContext

A JSContext object represents a JavaScript execution environment. You create and use JavaScript contexts to evaluate JavaScript scripts from Objective-C or Swift code, to access values defined in or calculated in JavaScript, and to make native objects, methods, or functions accessible to JavaScript.

 JavaScript Functions

We are using JSContext’s evaluateScript: method to define our JavaScript function. This method takes a string representation of some JavaScript code. Either include this string in a variable or load you JS from a file in your app's bundle.

Calling a JavaScript Function & using JSValue

A JSValue instance is a reference to a JavaScript value. You use the JSValue class to convert basic values (such as numbers and strings) between JavaScript and Objective-C or Swift representations in order to pass data between native code and JavaScript code.

Gotta Catch'em All

Now whenever a JavaScript exception occurs, the exception message (the value parameter passed into the block) will be logged. The exception will give us some helpful information about what went wrong in the JavaScript code.

context?.exceptionHandler = { context, exception in
        
    if let e = exception
    {
        print("JS Exception:", e.toString())
    }
}

Communicating with web views

func deviceInfo() 
{
    let color = "red"

    let javaScriptString = "changeColor(\(color));" 
    webView.evaluateJavaScript(javaScriptString, completionHandler: nil)
}


changeColor(color) {

    var x = document.getElementById("demo");   // Get the element with id="demo"
    x.style.color = color;                     // Change the color of the element
}

Calling Swift From JavaScript

  • We create a code block (let’s say a closure) that will be “passed” to the JavaScript runtime. This is the Swift code that is exposed to the “other side” (JavaScript), therefore in its body we write whatever we want to be executed when it gets called.
  • We convert that block into a AnyObject object.
  • We set that object to the JSContext and we specify a name that that JavaScript will use.
  • Evaluate that object in the JSContext.

Note: How to create a code block

let handler: @convention(block) ([Int]) -> Void = { numbers in
 
}


let something: @convention(block) (String, [String: String]) -> Void = { stringValue, dictionary in
 
}

Let's "code" 📱

Ευχαριστούμε 🎈

CocoaHeadsSKG

Dimitri James Tsiflitzis