JavascriptCore:在JSExport中将javascript函数作为参数传递

JavascriptCore是iOS7支持的新框架。 我们可以使用JSExport协议将部分objc类暴露给JavaScript。

在javascript中,我试图将函数作为参数传递。 像这样:

function getJsonCallback(json) { movie = JSON.parse(json) renderTemplate() } viewController.getJsonWithURLCallback("", getJsonCallback) 

在我的objc viewController中,我定义了我的协议:

 @protocol FetchJsonForJS  - (void)getJsonWithURL:(NSString *)URL callback:(void (^)(NSString *json))callback; - (void)getJsonWithURL:(NSString *)URL callbackScript:(NSString *)script; @end 

在javascript中,viewController.getJsonWithURLCallbackScript可以工作,但是,viewController.getJsonWithURLCallback不起作用。

我在JSExport中使用了块有什么错误吗? 谢谢。

问题是你已经将回调定义为采用NSString arg的Objective-C块,但javascript不知道如何处理这个并在你尝试评估viewController.getJsonWithURLCallback(“”,getJsonCallback)时产生exception – 它认为第二个参数的类型是’undefined’

相反,您需要将回调定义为javascript函数。

您可以使用JSValue在Objective-C中完成此操作。

对于其他读者,这是一个完整的工作示例(带有exception处理):

TestHarnessViewController.h:

 #import  #import  @protocol TestHarnessViewControllerExports  - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback; @end @interface TestHarnessViewController : UIViewController  @end 

TestHarnessViewController.m 🙁如果使用复制/粘贴,删除evaluateScript中的换行符 – 为了清楚起见添加了这些换行符):

 #import "TestHarnessViewController.h" @implementation TestHarnessViewController { JSContext *javascriptContext; } - (void)viewDidLoad { [super viewDidLoad]; javascriptContext = [[JSContext alloc] init]; javascriptContext[@"consoleLog"] = ^(NSString *message) { NSLog(@"Javascript log: %@",message); }; javascriptContext[@"viewController"] = self; javascriptContext.exception = nil; [javascriptContext evaluateScript:@" function getJsonCallback(json) { consoleLog(\"getJsonCallback(\"+json+\") invoked.\"); /* movie = JSON.parse(json); renderTemplate(); */ } viewController.getJsonWithURLCallback(\"\", getJsonCallback); "]; JSValue *e = javascriptContext.exception; if (e != nil && ![e isNull]) NSLog(@"Javascript exception occurred %@", [e toString]); } - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback { NSString *json = @""; // Put JSON extract from URL here [callback callWithArguments:@[json]]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end