Search code examples
javascriptswiftjavascriptcore

Catching print statement from JavaScript in Swift using JSContext


I'm trying to evaluate some JavaScript in my iOS app using JSContext. It's working well however I am not able to catch console.log() statements. How can I get the results of these function calls so I can print them in Swift as well?

Example Code

    let jsSource = "var testFunct = function(message) { console.log(\"kud\"); return \"Test Message: \" + message;}"

    let context = JSContext()
    context?.evaluateScript(jsSource)

    let testFunction = context?.objectForKeyedSubscript("testFunct")
    let result = testFunction?.call(withArguments: ["the message"])
    print(result!)

Example Logs

Test Message: the message


Solution

  • In case anyone is struggling with the same thing, here's the answer in Swift 4.

        let javascriptContext = JSContext()
    
        javascriptContext?.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
        let consoleLog: @convention(block) (String) -> Void = { message in
            print("console.log: " + message)
        }
        javascriptContext?.setObject(unsafeBitCast(consoleLog, to: AnyObject.self), forKeyedSubscript: "_consoleLog" as (NSCopying & NSObjectProtocol)!)
    

    Now you can call console.log() in any subsequent evaluateScript calls javascriptContext.