Возникли проблемы с использованием AFNetworking при получении JSON

Поэтому я недавно хотел перейти от использования NSURlConnection к AFNetworking. Я могу получать данные JSON обоими методами, но при использовании с AFNetworking происходит что-то странное.

Вот как это выглядит с NSURLConnection

введите здесь описание изображения

и вот как это выглядит с AFNetworking введите здесь описание изображения

Я понятия не имею, что это (struct __lidb_autoregen_nspair), и я не знаю, мешает ли мне отображать данные это.

Это код от AFNetworking, я использую пример кода от ray

-(void) fetchData{

// 1

NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

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

    // 3
    jsonDict = (NSMutableDictionary *)responseObject;



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

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

// 5
[operation start];

}

-------------------------------------------------- --------------------------------------- Редактировать

-(NSMutableDictionary *) getAllGames{

[self fetchData];

DataParser *dataParserObjec = [[DataParser alloc] init];

return [dataParserObjec sendBackAllGames:jsonDict];

}

person Timo Cengiz    schedule 02.12.2014    source источник
comment
acceptableContentTypes не должно быть application/json?   -  person Larme    schedule 02.12.2014
comment
Хм может быть проблема. Когда у меня не было этой строки кода, говорящей text/html, я попал в блок ошибок. Я предполагаю, что мой сервер не отправляет JSON, верно? Но почему это работает с NSURLConnection? @Ларме   -  person Timo Cengiz    schedule 02.12.2014
comment
Таким образом, единственное исправление здесь - заставить сервер отправлять обратно json правильно @rob   -  person Timo Cengiz    schedule 02.12.2014
comment
Я могу распечатать его, как вы предложили. Теперь я вижу проблему, но я не знаю, почему это так. jsonDict — это свойство в этом классе, и, как вы видите, я передаю значение из responseObject в jsonDict. В другом методе немного дальше я хочу отправить jsonDict, но почему значение nil для jsonDict? @Роб   -  person Timo Cengiz    schedule 02.12.2014
comment
Может быть, это потому, что он работает в фоновом режиме, а основной поток продолжает работать, и, как вы сказали, я отправляю пустой словарь, потому что он еще не закончил получение того, что мне нужно? ЕСЛИ это так, как бы я это исправить? @Роб   -  person Timo Cengiz    schedule 02.12.2014
comment
Давайте продолжим обсуждение в чате.   -  person Timo Cengiz    schedule 02.12.2014


Ответы (1)


  1. Вы устанавливаете acceptableContentTypes на text/html. Я предполагаю, что вы делаете это, потому что ваш веб-сервис не устанавливает правильный заголовок Content-Type, чтобы указать, что это application/json. Если вы исправили веб-службу для предоставления правильного заголовка Content-Type, вы могли бы удалить эту строку acceptableContentTypes в своем коде Objective-C.

    Если вам интересно, почему вам не нужно было беспокоиться об этом с NSURLConnection, это потому, что NSURLConnection не выполняет никакой проверки Content-Type (если, конечно, вы не пишете свой собственный код, например, didReceiveResponse, который проверял это ).

  2. Вы предполагаете, что не можете отобразить данные. Но вот оно, на втором снимке экрана. Лично я меньше беспокоюсь о внутреннем представлении, чем о том, могу ли я получить доступ к данным из NSDictionary. если ты

    NSLog(@"responseObject=%@", responseObject); 
    

    в #3, внутри блока успеха, что именно вы видите? Держу пари, вы увидите свой NSDictionary в порядке (несмотря на тонкие различия во внутреннем представлении).

    Я утверждаю, что вы успешно возвращаете данные. Да, ваш веб-сервис должен установить правильный заголовок Content-Type, чтобы вам не пришлось перезаписывать значение acceptableContentTypes, но похоже, что AFNetworking нормально извлекает ваши данные.

  3. Вероятная проблема заключается в том, что ваш основной поток пытается использовать jsonDict до выполнения асинхронного сетевого запроса. Таким образом, хитрость заключается в том, чтобы отложить использование jsonDict до тех пор, пока не будет выполнен асинхронный запрос.

    Вы обновили свой вопрос, показав нам, что вы создаете экземпляр DataParser и вызываете sendBackAllGames. Вы должны поместить этот код внутри блока завершения вашего асинхронного сетевого запроса.

    В качестве альтернативы вы можете использовать шаблон блока завершения в своем методе fetchData, а затем метод getAllGames может предоставить код sendBackAllGames в блоке завершения, который fetchData вызывает внутри блока успеха AFHTTPRequestOperation.


Если бы вы использовали шаблон блока завершения, это выглядело бы так:

-(void) fetchDataWithCompletionHandler:(void (^)(id responseObject, NSError *error))completionHandler {

    NSURL *url = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    // removed once we fixed the `Content-Type` header on server
    //
    // operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (completionHandler) {
            completionHandler(responseObject, nil);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [[[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather"
                                    message:[error localizedDescription]
                                   delegate:nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil] show];

        if (completionHandler) {
            completionHandler(nil, error);
        }
    }];

    [operation start];
}

И вы бы назвали это так:

[self fetchDataWithCompletionHandler:^(id responseObject, NSError *error) {
    if (responseObject) {
        DataParser *dataParserObjec = [[DataParser alloc] init];

        NSMutableDictionary *results = [dataParserObjec sendBackAllGames:jsonDict];

        // do whatever you want with results
    }
}];

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

person Rob    schedule 02.12.2014
comment
stackoverflow.com/questions/27280648/ - person Timo Cengiz; 04.12.2014
comment
stackoverflow.com/questions/27307814/ У меня была эта проблема некоторое время, и я никогда не мог ее решить. ты, кажется, много знаешь, может быть, ты имеешь представление о том, почему у меня возникла эта проблема @Rob - person Timo Cengiz; 07.12.2014