Тело ответа AFNetworking 500

Я использовал AFNetworking 2.0 в своем приложении. Я заметил, что если мой веб-сервис возвращает код состояния 500, я не получаю тело ответа.

Вот пример моего php-кода

try { $conn = new PDO( "sqlsrv:server=$serverName;Database = $database", $uid, $pwd); $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch( PDOException $e ) { $response->status(500); echo( "Connection Error: " . $e->getMessage() ); } 

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

 Connection Error: SQLSTATE[08001]: [Microsoft][SQL Server Native Client 11.0]SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF]. 

Однако, похоже, это единственный ответ, который я могу получить от AFNetworking

 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x15e58fa0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.} 

Это часть моего объектного кода c, который делает это.

 ...} failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error.description); }]; 

Есть ли способ получить тело ответа?

Изменить: Больше кода для уточнения

Ниже приведена часть моего подкласса AFHTTPSessionManager

 @implementation MSMAMobileAPIClient + (MSMAMobileAPIClient *)sharedClient { static MSMAMobileAPIClient *_sharedClient = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedClient = [[MSMAMobileAPIClient alloc] initWithDefaultURL]; }); return _sharedClient; } - (id)initWithDefaultURL { return [self initWithBaseURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://%@/mamobile/index.php/" ,[[NSUserDefaults standardUserDefaults] stringForKey:@"serviceIPAddress"]]]]; } - (id)initWithBaseURL:(NSURL *)url { self = [super initWithBaseURL:url]; if (!self) { return nil; } self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:@[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]]; return self; } 

Я попытался установить сериализатор ответа на AFCompoundResponseSerializer, но, похоже, он не изменил ситуацию

Ниже приведен пример подкласса, который я называю библиотекарем.

 -(void)searchForItemWithString:(NSString *)searchString withCompletionBlock:(arrayBlock)block { self.inventorySearchBlock = block; NSDictionary *parameters = @{@"query": searchString}; [[MSMAMobileAPIClient sharedClient] GET:@"inventory/search" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { if (!responseObject) { NSLog(@"Error parsing JSON"); } else { //do stuff with the json dictionary that's returned.. } } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"Error: %@",error.description); }]; } 

3 Solutions collect form web for “Тело ответа AFNetworking 500”

UPDATE: я создал репозиторий github, содержащий последний код, который я использую. Все изменения будут опубликованы там. https://github.com/Hackmodford/HMFJSONResponseSerializerWithData

Ответ исходит из этой проблемы на github. https://github.com/AFNetworking/AFNetworking/issues/1397

gfiumara – это разработчик, который придумал это. Я только немного изменил свой подкласс AFJSONResponseSerializer, чтобы включить фактическую строку вместо NSData

 //MSJSONResponseSerializerWithData.h #import "AFURLResponseSerialization.h" /// NSError userInfo key that will contain response data static NSString * const JSONResponseSerializerWithDataKey = @"JSONResponseSerializerWithDataKey"; @interface MSJSONResponseSerializerWithData : AFJSONResponseSerializer @end 

 // MSJSONResponseSerializerWithData.m #import "MSJSONResponseSerializerWithData.h" @implementation MSJSONResponseSerializerWithData - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (*error != nil) { NSMutableDictionary *userInfo = [(*error).userInfo mutableCopy]; userInfo[JSONResponseSerializerWithDataKey] = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:userInfo]; (*error) = newError; } return (nil); } return ([super responseObjectForResponse:response data:data error:error]); } @end 

Вот пример того, как я использую его в блоке отказов.

 } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",[error.userInfo objectForKey:@"JSONResponseSerializerWithDataKey"]); }]; 

Вам необходимо использовать AFCompoundSerializer чтобы сообщить структуре AFNetworking, как обрабатывать все возможные ответы, которые он может получить. По умолчанию он попытается отобразить JSON. Составной сериализатор будет работать через сериализаторы, пока не найдет тот, который не вызывает ошибку.


Вы хотите использовать:

 + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers 

на AFCompoundResponseSerializerAFURLResponseSerialization.h ).

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

Если вы включите мою категорию в свой проект, это будет так просто:

 [mySessionManager POST:@"some-api" parameters:params success:^(NSURLSessionDataTask *task, NSDictionary *responseObject) { ... } failure:^(NSURLSessionDataTask *task, NSError *error) { id responseObject = error.userInfo[kErrorResponseObjectKey]; ... do something with the response ... }]; 

Вот код для моей категории. Он запускает AFURLSessionManager для вставки прокладки в обработчик завершения. Прокладка помещает ответ в пользовательскую информацию NSError.

https://gist.github.com/chrishulbert/35ecbec4b37d36b0d608

  • Вызов AFHTTPSessionManager.downloadTasks в AFNetworking 2 замораживает основной поток
  • AFNetworkingReachabilityManager отключен при запуске приложения, когда iPhone подключен к Wi-Fi
  • AFNetworking HTTP удаляет использование тела вместо URL
  • Как добиться загрузки в AFNetworking 2.0?
  • Мониторинг достижимости с AFNetworking только на представленном контроллере
  • AFNetworking 2.0: передача информации заголовка
  • AFNetworking и фоновые переводы
  • Wanted: обновленный пример для JSON / POST с базовым авторизацией с использованием AFNetworking-2
  • Замена для AFJSONRequestOperation в AFNetworking 2.x
  • Функция запуска при полной загрузке ионной 2 страницы
  • Настройка доступности с помощью AFNetworking 2.0
  • Как установить заголовок по умолчанию для AFNetworking 2.0?
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.