JavascriptCore: pasa la function javascript como parámetro en JSExport

JavascriptCore es un nuevo marco compatible con iOS7. Podemos usar el protocolo JSExport para exponer partes de la class objc a JavaScript.

En javascript, intenté pasar la function como parámetro. Así como esto:

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

En mi objc viewController, definí mi protocolo:

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

En javascript, viewController.getJsonWithURLCallbackScript funciona, sin embargo, viewController.getJsonWithURLCallback no funciona.

¿Hay algún error que utilicé bloquear en JSExport? Gracias.

El problema es que ha definido la callback como un bloque Objective-C tomando un NSString arg pero javascript no sabe qué hacer con esto y produce una exception cuando intenta evaluar viewController.getJsonWithURLCallback ("", getJsonCallback) – piensa el tipo del segundo parámetro es 'indefinido'

En su lugar, debe definir la callback como una function javascript.

Puede hacer esto en Objective-C simplemente usando JSValue.

Para otros lectores, aquí hay un ejemplo de trabajo completo (con event handling excepciones):

TestHarnessViewController.h:

 #import <UIKit/UIKit.h> #import <JavaScriptCore/JavaScriptCore.h> @protocol TestHarnessViewControllerExports <JSExport> - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback; @end @interface TestHarnessViewController : UIViewController <TestHarnessViewControllerExports> @end 

TestHarnessViewController.m: (si usa copyr / pegar, elimine las líneas nuevas dentro de evaluateScript, éstas se agregaron para mayor claridad):

 #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 occurnetworking %@", [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