如何在Swift中使用JavaScriptCore从JavaScript SDK调用异步JavaScript函数

5
我正在尝试使用JSCore从Swift中执行一个javascript SDK中的异步函数。我已经成功评估并查看了脚本内容,但是在实际调用异步函数时失败了。这是我的代码,以验证我是否已读取脚本。有关如何完成此操作的想法吗?
lazy var context: JSContext? = {
    let context = JSContext()

    guard let
        commonJSPath = Bundle.main.path(forResource: "test", ofType: "js") else {
            print("Unable to read resource files.")
            return nil
    }

    do {
        let common = try String(contentsOfFile: commonJSPath, encoding: String.Encoding.utf8)
        _ = context?.evaluateScript(common)
    } catch (let error) {
        print("Error while processing script file: \(error)")
    }

    return context
}()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    setupJS()

}

func setupJS(){
    guard let context = context else {
        print("JSContext not found.")
        return
    }

    let dictionary = context.objectForKeyedSubscript("MainObject").toDictionary()
    print(dictonary)
    //let script = "const {variableName} = FooJS;";
    //let result = context.evaluateScript(script)

}

我想要做类似于 async function doSomething(){ return 'hello world!'; } console.log(await doSomething());

的事情。


你怎么知道它没有成功?问题在于你是否期望Swift运行时等待某些同步的“完成”或其他操作吗? - Pointy
我有两个问题,一个是在Swift中对实际函数进行下标调用,另一个是等待结果。 - iPhonig
1个回答

4
调用 JavaScript 函数的 Swift 代码示例:
context.objectForKeyedSubscript("functionName_in_Javascript_file").call(withArguments: [])

为了将控制权交回给Swift,您可以定义一个块以从JavaScript中调用,如下所示:
// someString 可能是您需要从JavaScript获取的结果。
let swiftHandler: @convention(block) (String) -> Void = {(someString) in
        //do something
    }

//像这样将块设置为JavaScript可用:

let swiftBlock = unsafeBitCast(swiftHandler, to: AnyObject.self)

context.setObject(swiftBlock, forKeyedSubscript: "swiftCallback" as (NSCopying & NSObjectProtocol)!)

//最后,在您的JavaScript文件中,当您获得所需的结果时,只需使用先前指定的名称调用Swift函数:

swiftCallback(result);

是否有一种无需回调函数等待JS函数的方法? - Byurhan Beyzat
有人能给一个完整的例子来说明这个解决方案吗?我似乎无法将其适应到我的情况中。谢谢。 - Julia
当我尝试使用这些代码片段时,我会收到关于context.setObject()行的错误提示:"可选类型 'JSContext?' 的值必须被解包才能引用封装基础类型 'JSContext' 的成员'setObject'"。 - Julia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接