2

假设我有一个 javascript 文件,javascript.js其中包含以下内容。

window.fruitsAndVeggies = {
    name2CategoryMap: {
        "apple": "fruit",
        "carrot": "vegetable"
    }
}

谁能告诉我将 Javascript 对象的内容window.fruitsAndVeggies放入 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 );

我很困惑下一步该做什么。我需要使用fruitsAndVeggies.name2CategoryMap我的 Objective-C 代码中的内容。访问它们的最简单方法是什么?我可以调用一个简单的函数将它们加载到objective-c字典中吗?

非常感谢您的帮助。

4

2 回答 2

0

尽我所能,我想不出一个优雅的方法来window.fruitsAndVeggies查字典。我能做的最好的事情是手动滚动一个循环,遍历 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);

}

输出:

key apple has value fruit
key carrot has value vegetable
于 2013-11-04T18:40:12.220 回答
0

自从 iOS 7 引入 JavaScriptCore 中的新 Objective-C 接口以来,事情变得简单了很多。有关此的介绍,请参阅 Apple 开发人员网络上的 WWDC 2013 会议“将 JavaScript 集成到本机应用程序”会议:https://developer。 apple.com/videos/wwdc/2013/?id=615

评估 javascript 资源文件后您需要的代码是:

    JSContext *context = [JSContext contextWithJSGlobalContextRef:ctx];
    NSDictionary *fruitsAndVeggiesDict = [context[@"window"][@"fruitsAndVeggies"][@"name2CategoryMap"] toObject];

    NSLog(@"name2CategoryMap['apple'] = %@", fruitsAndVeggiesDict[@"apple"]);
    NSLog(@"name2CategoryMap['carrot'] = %@", fruitsAndVeggiesDict[@"carrot"]);
于 2014-02-09T00:15:00.687 回答