简体   繁体   English

使用javascriptcore框架调用javascript函数会将[object Object]返回给JSValue

[英]Calling javascript functions using javascriptcore framework returns [object Object] to JSValue

Code in .js file: .js文件中的代码:

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

objective-c native methods: 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;
    }

In the above code, the method 'callingWeatherFromJavascript' returns NSDictionary . 在上面的代码中,方法'callingWeatherFromJavascript'返回NSDictionary When i receive this value in "JSValue" in function '-(void)runJS' it returns [object Object] . 当我在函数'-(void)runJS' “ JSValue”中接收到此值时,它将返回[object Object] Is there any way of converting this back into NSDictionary ? 有什么办法可以将其转换回NSDictionary吗?

I don't want to take credit away from vivek_ios, he answered his own question. 我不想忘记vivek_ios,他回答了自己的问题。 I just want to rewrite his response so it's clearer and easier to re-use because it took me a while to find the answer in the comments. 我只想重写他的回答,以便更清晰,更轻松地重复使用,因为我花了一些时间才能在评论中找到答案。

Basically, converting JSValue to NSDictionary is simply done via JSValue.toDictionary. 基本上,将JSValue转换为NSDictionary只需通过JSValue.toDictionary完成。 Something like this: 像这样:

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

First covert your response object to NSData 首先隐藏您对NSData的响应对象

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

Then create NSDictionary with JSON serialization as it looks like you are receiving JSON object from your webservice 然后使用JSON序列化创建NSDictionary,就像您从Web服务接收JSON对象一样

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

Then you should be able to access your "main" key and get all info from here. 然后,您应该能够访问“主”键并从此处获取所有信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM