如何使用JavaScriptCore将javascript对象转换为NSDictionary
假设我有一个javascript文件,如何使用JavaScriptCore将javascript对象转换为NSDictionary,javascript,objective-c,javascriptcore,Javascript,Objective C,Javascriptcore,假设我有一个javascript文件,javascript.js,包含以下内容 window.fruitsAndVeggies = { name2CategoryMap: { "apple": "fruit", "carrot": "vegetable" } } 有谁能告诉我将Javascript对象window.fructsandvegies的内容放入NSDictionary的最简单方法吗 我从互联网上的各种来源拼凑了以下代码片段,它创建了一个
javascript.js
,包含以下内容
window.fruitsAndVeggies = {
name2CategoryMap: {
"apple": "fruit",
"carrot": "vegetable"
}
}
有谁能告诉我将Javascript对象window.fructsandvegies
的内容放入NSDictionary的最简单方法吗
我从互联网上的各种来源拼凑了以下代码片段,它创建了一个Javascript上下文,然后在该上下文中计算Javascript代码
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 );
我不知道下一步该怎么办。我需要在objective-c代码中使用水果和蔬菜.name2CategoryMap
的内容。访问它们最简单的方法是什么?我可以调用一个简单的函数将它们加载到objective-c字典中吗
非常感谢您的帮助。尽管我尽了最大努力,我还是想不出一个优雅的方法来将
窗口中的水果和蔬菜
放入字典。我所能做的最好的事情就是手动滚动一个循环,循环遍历javascript对象,并将每个键/值对逐个添加到字典中
代码如下。注意:这很难看。如果你有更简洁的解决方案,我洗耳恭听
/* Make the dictionary. */
NSMutableDictionary *fruitsAndVeggiesDict = [NSMutableDictionary dictionary];
/* In the JS context, create a variable called "keys".
Return the number of keys (keys.length). */
result = JSEvaluateScript( ctx, JSStringCreateWithUTF8CString("var keys = Object.keys(window.fruitsAndVeggies.name2CategoryMap); keys.length"), NULL, NULL, 0, &exception );
double numKeys = JSValueToNumber(ctx, result, &exception);
/* Iterate over the keys; convert each key/value into a pair of NSStrings. */
for(int i = 0; i < numKeys; i++){
// get a key, save in keyStrNS
NSString *getKeyStr = [NSString stringWithFormat:@"keys[%d]", i];
CFStringRef getKeyStrCF = (__bridge CFStringRef)getKeyStr;
JSStringRef getKeyStrJS = JSStringCreateWithCFString(getKeyStrCF);
JSValueRef key = JSEvaluateScript( ctx, getKeyStrJS, NULL, NULL, 0, &exception );
JSStringRef keyStrJS = JSValueToStringCopy(ctx, key, &exception);
NSString *keyStrNS = (NSString *)JSStringCopyCFString( kCFAllocatorDefault, keyStrJS );
// get a value, save in valueStrNS
NSString *getValueStr = [NSString stringWithFormat:@"window.fruitsAndVeggies.name2CategoryMap[\"%@\"]", keyStrNS];
CFStringRef getValueStrCF = (__bridge CFStringRef)getValueStr;
JSStringRef getValueStrJS = JSStringCreateWithCFString(getValueStrCF);
JSValueRef value = JSEvaluateScript( ctx, getValueStrJS, NULL, NULL, 0, &exception );
JSStringRef valueStrJS = JSValueToStringCopy(ctx, value, &exception);
NSString *valueStrNS = (NSString *)JSStringCopyCFString( kCFAllocatorDefault, valueStrJS );
/* store the key and value in our dictionary */
[fruitsAndVeggiesDict setObject: valueStrNS forKey: keyStrNS];
/* and print them for good measure */
NSLog(@"key %@ has value %@",keyStrNS,valueStrNS);
}
自从iOS7引入JavaScriptCore中新的Objective-C接口以来,事情变得简单多了。有关这方面的介绍,请参阅苹果开发者网络上的WWDC 2013会议“将JavaScript集成到本机应用程序”会议: 评估javascript资源文件后需要的代码是:
JSContext *context = [JSContext contextWithJSGlobalContextRef:ctx];
NSDictionary *fruitsAndVeggiesDict = [context[@"window"][@"fruitsAndVeggies"][@"name2CategoryMap"] toObject];
NSLog(@"name2CategoryMap['apple'] = %@", fruitsAndVeggiesDict[@"apple"]);
NSLog(@"name2CategoryMap['carrot'] = %@", fruitsAndVeggiesDict[@"carrot"]);
JSContext *context = [JSContext contextWithJSGlobalContextRef:ctx];
NSDictionary *fruitsAndVeggiesDict = [context[@"window"][@"fruitsAndVeggies"][@"name2CategoryMap"] toObject];
NSLog(@"name2CategoryMap['apple'] = %@", fruitsAndVeggiesDict[@"apple"]);
NSLog(@"name2CategoryMap['carrot'] = %@", fruitsAndVeggiesDict[@"carrot"]);