【问题标题】:Calling javascript functions using javascriptcore framework returns [object Object] to JSValue使用 javascriptcore 框架调用 javascript 函数将 [object Object] 返回到 JSValue
【发布时间】:2014-05-12 10:27:17
【问题描述】:

.js 文件中的代码:

var fact = function(x){
    return WeatherWebService(x);
}   

objective-c 原生方法:

 - (IBAction)btnOkClicked:(id)sender 
    {
        [self.aJSEngine loadJSLibrary:@"script"];    
    }

    - (void)loadJSLibrary:(NSString*)libraryName
    {
        NSString *library = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:libraryName ofType:@"js"]  encoding:NSUTF8StringEncoding error:nil];

        NSLog(@"[JSC] loading library %@...", libraryName);
        [self runJS:library];
    }

    - (void)runJS:(NSString *)aJSString
    {
        if (!aJSString) {
            NSLog(@"[JSC] JS String is empty!");
        }
        else{
            JSContext *context = [[JSContext alloc]initWithVirtualMachine:[[JSVirtualMachine alloc]init]];
            context[@"WeatherWebService"] = ^(int x){
                NSDictionary *dict = [self callingWeatherFromJavascript];
                return dict;
            };

            [context evaluateScript:aJSString];
            JSValue *val = context[@"fact"];
            JSValue *finalResult = [val callWithArguments:@[context[@"3"]]];

        }
    }

    -(NSDictionary*)callingWeatherFromJavascript{
            NSString *urlString =  @"http://api.openweathermap.org/data/2.5/weather?q=London,uk";
            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
            __block BOOL complete = NO;
            AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
            operation.responseSerializer = [AFJSONResponseSerializer serializer];

            [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

                // 3
                self.dictionary = (NSDictionary *)responseObject;
                complete=YES;
                // NSDictionary *dict = [self.dictionary objectForKey:@"main"];
                //            if ([self.delegate respondsToSelector:@selector(returnDataFromResponse:)]) {
                //                [self.delegate returnDataFromResponse:dict];
                //            }

            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                // 4
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather"
                                                                    message:[error localizedDescription]
                                                                   delegate:nil
                                                          cancelButtonTitle:@"Ok"
                                                          otherButtonTitles:nil];
                complete=NO;
                [alertView show];
            }];


            // 5
            [operation start];
        while(complete == NO) {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
        }
        return self.dictionary;
    }

在上面的代码中,方法'callingWeatherFromJavascript'返回NSDictionary。当我在函数'-(void)runJS' 的“JSValue”中收到这个值时,它返回[object Object]。有什么办法可以将其转换回NSDictionary

【问题讨论】:

  • 什么是[object Object]?是 JSON、XML 还是其他?
  • NSDictionary 类型的对象。
  • 给我一些示例数据,我会告诉你如何将它转换回 NSDictionary
  • id = 2643743;基地=“cmc站”;云= {全部= 36; };鳕鱼 = 200;主要= {“grnd_level”=“1013.19”;湿度 = 78;压力=“1013.19”; "sea_level" = "1023.2";温度=“284.491”; "temp_max" = "284.491"; "temp_min" = "284.491"; };
  • 这是我想要的上述格式

标签: javascript ios objective-c javascriptcore


【解决方案1】:

我不想从 vivek_ios 拿走荣誉,他回答了自己的问题。我只是想重写他的回复,以便更清晰、更容易重复使用,因为我花了一段时间才在 cmets 中找到答案。

基本上,将 JSValue 转换为 NSDictionary 只需通过 JSValue.toDictionary 完成。像这样的:

JSContext *jsContext  = [JSContext new];
[jsContext evaluateScript:[NSString stringWithContentsOfFile:myJavascriptFilePath encoding:NSUTF8StringEncoding error:nil]];
NSDictionary *result = [jsContext[@"myJavascriptFunction"] callWithArguments:@[optionalArgument]].toDictionary;

【讨论】:

    【解决方案2】:

    首先将您的响应对象转换为 NSData

    NSData *responseData = [[NSData alloc]initWithContentsOfFile:(NSString*)responseObject encoding:NSUTF8StringEncoding error:nil];
    

    然后使用 JSON 序列化创建 NSDictionary,因为看起来您正在从您的 Web 服务接收 JSON 对象

    NSDictionary *responceDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
    

    那么你应该能够访问你的“主”键并从这里获取所有信息。

    【讨论】:

    • 我刚刚对 JavaScriptCore 框架进行了一些探索,我真的找到了一种非常简单的方法。 [上下文评估脚本:aJSString]; JSValue *val = context[@"fact"]; JSValue *finalResult = [val callWithArguments:@[context[@"3"]]]; NSDictionary *responceDictionary = finalResult.toDictionary;有一个名为 toDictionary 的函数将 javascript 对象转换为 NSDictionary
    猜你喜欢
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 2022-11-14
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多