JavaScriptCore — Passing a function as a parameter to ObjC

纵然是瞬间 提交于 2019-12-08 07:35:33

问题


I have a UIWebView that utilizes JavaScriptCore. I'm trying to call an ObjC function from an web page. However, the function needs to be call asynchronously, so I'm passing in a callback function that is called when the async ObjC function is called.

It is my understanding that JS functions are equivalent to NSBlock via the bridge. The current code I have is:

context[@"currentUserLocation"] = ^( void(^callback)(NSString* str) )
{
    NSLog(@"Starting Async Function");

    //generic async function
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"delay complete");
        callback( @"return value" );
    });
};

Is there something fundamentally wrong with what I'm doing? On the surface it seems like ObjC won't know what context to run the callback function in.


回答1:


It took me a little while to get the hang of this. The trick is not to think of the callback argument as a block, but a JSValue and then call it using the JSValue API:

context[@"currentUserLocation"] = ^(JSValue *callback)
{
    NSLog(@"Starting Async Function");

    //generic async function
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"delay complete");
        //Check we actually have a callback (isObject is the best we can do, there is no isFunction)
        if ([callback isObject] != NO) {
            //Use window.setTimeout to schedule the callback to be run
            [context[@"setTimeout"] callWithArguments:@[callback, @0, @"return value"]];
        }
    });
};

Wrapping the callback in a window.setTimeout() call allows the JSVirtualMachine to take care of scheduling and threading, I have found calling the callback directly often leads to deadlocks if any UI work is done by the callback.



来源:https://stackoverflow.com/questions/22790355/javascriptcore-passing-a-function-as-a-parameter-to-objc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!