Let's say I have a javascript file, javascript.js
, with the following content.
window.fruitsAndVeggies = {
name2CategoryMap: {
"apple": "fruit",
"carrot": "vegetable"
}
}
Can anyone tell me the easiest way to get the contents of the Javascript object window.fruitsAndVeggies
into an NSDictionary?
From various sources on the internet I've pieced together the following snippet, that creates a Javascript context, and then evaluates the javascript code in that context.
JSGlobalContextRef ctx = JSGlobalContextCreate(NULL); // create context
JSValueRef exception = JSValueMakeUndefined(ctx); // create object to hold exceptions
// Make a "window" object in the JS Context
JSStringRef makeWindowScript = JSStringCreateWithUTF8CString("var window = {}");
JSValueRef result = JSEvaluateScript( ctx, makeWindowScript, NULL, NULL, 0, &exception );
// load the javascript file into an NSString
NSBundle * bundle = [NSBundle bundleWithIdentifier:@"my.bundle"];
NSString *filePath = [bundle pathForResource:@"javascript" ofType:@"js"];
NSError *error;
NSString *stringFromFile = [[NSString alloc]
initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:&error];
// convert NSString to a JSStringRef
CFStringRef cfString = (__bridge CFStringRef)stringFromFile;
JSStringRef jsString = JSStringCreateWithCFString(cfString);
// evaluate the javascript
JSEvaluateScript( ctx, jsString, NULL, NULL, 0, &exception );
I'm confused as to what to do next. I need to use the contents of fruitsAndVeggies.name2CategoryMap
in my objective-c code. What's the easiest way to access them? Is there a simple function I can call to load them into an objective-c dictionary?
Many thanks for your help.
Things have become a lot simpler since the new Objective-C interface in JavaScriptCore introduced with iOS 7. For an intro to this, see the WWDC 2013 session "Integrating JavaScript into Native Apps" session on Apple's developer network: https://developer.apple.com/videos/wwdc/2013/?id=615
The code you need after evaluating the javascript resource file is:
JSContext *context = [JSContext contextWithJSGlobalContextRef:ctx];
NSDictionary *fruitsAndVeggiesDict = [context[@"window"][@"fruitsAndVeggies"][@"name2CategoryMap"] toObject];
NSLog(@"name2CategoryMap['apple'] = %@", fruitsAndVeggiesDict[@"apple"]);
NSLog(@"name2CategoryMap['carrot'] = %@", fruitsAndVeggiesDict[@"carrot"]);