Ответ JSON в postPath AFHTTPClient

Я только что переключился на RestKit 0.2 и в настоящее время использую новый «HttpClient», который в основном является AFHTTPClient. У меня есть такая строка кода:

RKObjectManager* objectManager = [RKObjectManager sharedManager];
NSDictionary* params = [[NSDictionary alloc] initWithObjectsAndKeys: login, @"username", password, @"password", nil];

[[objectManager HTTPClient]postPath:@"users/login/?format=json" parameters:params
    success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        //reponseObject vs operation.response
        NSLog(@"%@", responseObject);
    }
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        NSLog(@"ERROR");
    }];

Эти вызовы POST возвращают ответ JSON в форме: {"api_key": "....", "username": "...."}. Так просто.

Перед переключением на 0.2 я смог получить в ответе ключ api_key, выполнив следующие действия:

 [[RKClient sharedClient] post:@"/users/login/?format=json" usingBlock:^(RKRequest *request)
 {
    request.onDidLoadResponse = ^(RKResponse *response)
    {
        id parsedResponse = [response parsedBody:NULL];
        NSString *apiKey = [parsedResponse valueForKey:@"api_key"];
    }
  }.....];

http://restkit.org/api/master/Classes/RKResponse.html

Но теперь я не могу этого сделать, и если я сделаю NSLog для responseObject, я получаю:

<7b227265 61736f6e 223a2022 41504920 4b657920 666f756e 64222c20 22617069 5f6b6579 223a2022 61356661 65323437 66336264 35316164 39396338 63393734 36386438 34636162 36306537 65386331 222c2022 73756363 65737322 3a207472 75657d>

И что странно, если я это сделаю:

        NSLog(@"%@", operation.responseString);

У меня есть JSON (в NSString).

Итак, два вопроса:

1) Почему при печати responseObject отображается шестнадцатеричный код, а не фактический ответ JSON?

2) Почему, если я выполняю операцию operation.responseString, отображается фактический объект ответа? Есть ли способ получить фактические данные в ResponseObject после анализа из JSON?


person abisson    schedule 14.11.2012    source источник


Ответы (2)


Если я не ошибаюсь, вы видите необработанные байты из NSData, которые передаются вам при вызове вашего блока успеха.

Публикуемый вами шестнадцатеричный текст гласит:

{"reason": "API Key found", "api_key": "a5fae247f3bd51ad99c8c97468d84cab60e7e8c1", "success": true}

Причина, по которой второй NSLog показывает вам то, что вы хотите, заключается в том, что строка формата %@ вызывает описание (поправьте меня, если я ошибаюсь, SO) объекта, который вы ей передаете, и NSData, вероятно, знает, что это строка внизу.

Итак, о том, как получить JSON. Это действительно довольно просто. Когда у вас есть объект ответа, вы можете сделать что-то вроде этого:

NSDictionary* jsonFromData = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

Что это будет делать для вас, так это использовать return NSDictionary, который кодирует корневой объект в JSON, и тогда каждое значение в словаре будет иметь тип NSString, NSNumber, NSArray, NSDictionary или NSNull. См. Документацию NSJSONSserialization.

NSJSONReadingMutableContainers делает словари и массивы изменяемыми. Это просто остаток моего кода.

Надеюсь, у вас iOS 5 или новее, или вам нужно будет найти другое решение для синтаксического анализа.

person DanBlakemore    schedule 01.12.2012
comment
Хотя это правильный ответ, но я думаю, что @ phix23 лучше, по крайней мере, для AFNetworking lib. ;) - person Kjuly; 07.06.2013

AFNetworking должен создать экземпляр AFJSONRequestOperation. Вероятно, вместо этого он создает базовый AFHTTPRequestOperation (проверьте [operation class]), в результате чего в качестве ответа будет получен объект NSData.

Убедитесь, что вы зарегистрировали класс операции в методе инициализации подкласса AFHTTPClient (initWithBaseURL):

[self registerHTTPOperationClass:[AFJSONRequestOperation class]];

// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:@"Accept" value:@"application/json"];

Вы также можете попробовать использовать AFJSONRequestOperation напрямую следующим образом:

NSURLRequest *request = [[objectManager HTTPClient] requestWithMethod:@"POST" path:@"users/login/?format=json" parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"JSON: %@", JSON);
} failure:nil];
[[objectManager HTTPClient] enqueueHTTPRequestOperation:operation];
person Felix    schedule 01.12.2012
comment
+1 за право использования AFNetworking. Следует принять это. - person Kjuly; 07.06.2013