Вызов функций javascript с использованием платформы javascriptcore возвращает [object Object] в JSValue

Код в .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. Когда я получаю это значение в «JSValue» в функции '-(void)runJS', оно возвращает [object Object]. Есть ли способ преобразовать это обратно в NSDictionary?


person vivek_ios    schedule 12.05.2014    source источник
comment
Что такое [объект Объект]? Это JSON, XML или что-то еще?   -  person Pancho    schedule 12.05.2014
comment
Тип объекта NSDictionary.   -  person vivek_ios    schedule 12.05.2014
comment
дайте мне несколько примеров данных, и я дам вам знать, как преобразовать их обратно в NSDictionary   -  person Pancho    schedule 12.05.2014
comment
идентификатор = 2643743; база = станции CMC; облака = { все = 36; }; треска = 200; основной = { grnd_level = 1013.19; влажность = 78; давление = 1013,19; уровень моря = 1023,2; температура = 284,491; temp_max = 284,491; temp_min = 284,491; };   -  person vivek_ios    schedule 12.05.2014
comment
это то, что я хочу в вышеуказанном формате   -  person vivek_ios    schedule 12.05.2014
comment
Хорошо, позвольте мне проверить, правильно ли я понял. Вы оцениваете некоторый JavaScript, и этот JS возвращает объект, который вы хотите преобразовать обратно в NSDictionary. Это правильно, или вы хотите изменить свой объект в JS, чтобы он выглядел как NSDictionary в Objective C? Который из них?   -  person Pancho    schedule 12.05.2014
comment
да JS возвращает объект, который я хочу преобразовать обратно в NSDictionary.   -  person vivek_ios    schedule 12.05.2014
comment
Вы пробовали [finalResult toDictionary]?   -  person Amozoss    schedule 16.05.2014


Ответы (2)


Я не хочу присваивать себе заслуги vivek_ios, он сам ответил на свой вопрос. Я просто хочу переписать его ответ, чтобы он был понятнее и проще для повторного использования, потому что мне потребовалось некоторое время, чтобы найти ответ в комментариях.

По сути, преобразование JSValue в NSDictionary просто выполняется с помощью JSValue.toDictionary. Что-то вроде этого:

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

Сначала скройте свой объект ответа в NSData

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

Затем создайте NSDictionary с сериализацией JSON, поскольку похоже, что вы получаете объект JSON из своего веб-сервиса.

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

Затем вы сможете получить доступ к своему «основному» ключу и получить всю информацию отсюда.

person Pancho    schedule 12.05.2014
comment
я только что немного изучил структуру JavaScriptCore, я действительно нашел очень простой способ сделать это. [контекст оценить скрипт: aJSString]; JSValue *val = контекст[@fact]; JSValue *finalResult = [val callWithArguments:@[context[@3]]]; NSDictionary *responceDictionary = finalResult.toDictionary; есть функция toDictionary для преобразования объекта javascript в NSDictionary - person vivek_ios; 12.05.2014