Принятие недопустимого JSON в AFJSONRequestOperation?

Я работаю над исправлением ошибки в существующем проекте. Проблема в том, что AFHTTPClient ожидает действительный ответ JSON, но сервер возвращает какую-то тарабарщину вроде ""\" Операция завершена\"" (в ответе все кавычки и скобки). Это приводит к сбою операции и попаданию блок fail, потому что он не может проанализировать ответ.Несмотря на это, сервер возвращает код состояния 200 и рад, что операция завершена.

У меня есть класс, который расширяет AFHTTPClient таким образом (из моего файла .h)

@interface AuthClient : AFHTTPClient

  //blah blah blah

@end

В моем файле реализации класс инициализируется так:

- (id)initWithBaseURL:(NSURL *)url{
    if (self = [super initWithBaseURL:url]) {        
        self.parameterEncoding = AFFormURLParameterEncoding;
        self.stringEncoding = NSASCIIStringEncoding;

        [self setDefaultHeader:@"Accept" value:@"application/json"];
        [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    }

    return self;
}

Вызов, который я делаю, выполняется в классе, упомянутом выше, и происходит так:

- (void)destroyToken:(NSString *)token onCompletion:(void (^)(BOOL success))completion onFailure:(void (^)(NSError *error))failure{

    [self postPath:@"TheServerURL" parameters:@{@"token": token} success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError *error;
        //Do some stuff
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        //Don't want to be here.
    }];
}

Внутри блока сбоя ошибка возвращается в разделе _userInfo объекта ошибки как:

[0] (null) @"NSDebugDescription" : @"Текст JSON не начинался с массива или объекта, а параметр разрешения фрагментов не установлен."

Код ошибки 3480.

Из поиска в Google я понял, что мне нужно установить что-то вроде NSJSONReadingAllowFragments, но я не уверен, как/где, учитывая текущую настройку. У кого-нибудь есть идеи?


person Rob    schedule 13.11.2013    source источник
comment
Когда сервер отвечает недопустимым JSON, почему служба не исправлена?   -  person CouchDeveloper    schedule 14.11.2013
comment
Исправление сервера запланировано, но какое-то время оно не будет отложено. Это вне моего контроля. Однако это отбрасывает мой график испытаний.   -  person Rob    schedule 15.11.2013


Ответы (1)


Похоже, ответ вовсе не JSON. Итак, почему бы просто не принять сам ответ HTTP, а не пытаться обрабатывать его как JSON, когда это не так?

Если вы отправляете сформированный запрос JSON, но просто хотите вернуть текстовый ответ, используя AFNetworking 2.0, вы можете сделать что-то вроде:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:urlString parameters:@{@"token":token} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    NSLog(@"responseString: %@", string);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Or, in 1.x:

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
client.parameterEncoding = AFJSONParameterEncoding;
NSMutableURLRequest *request = [client requestWithMethod:@"POST" path:path parameters:@{@"token" : token}];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    NSLog(@"response: %@", string);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[client enqueueHTTPRequestOperation:operation];
person Rob    schedule 13.11.2013
comment
Я бы предпочел сделать так, как вы предложили, но это большой класс, и он работает на 98%. Это всего лишь одна конечная точка, которая возвращает недопустимый JSON. Рефакторинг всего класса потребует продолжительного возвращения к QA, так что на данный момент это не вариант. Спасибо за отличный ответ. В 99% случаев это был бы идеальный ответ! Я понимаю, что моя ситуация — крайний случай. - person Rob; 14.11.2013
comment
@Rob (я чувствую, что разговариваю сам с собой :) Понял (и спасибо за согласие, хотя на самом деле я не решил ваш вопрос). Можете ли вы изменить свой класс, чтобы он всегда использовал AFHTTPRequestOperation, а затем вызывал JSONObjectWithData, возвращая объект JSON, если этот вызов прошел успешно, и NSData, если нет? Похоже на потенциальное изменение, которое не сломает остальную часть вашего кода. Очевидно, как предложил CouchDeveloper, лучшее решение — исправить веб-службу, чтобы она возвращала JSON (возможно, делая это условно, проверяя параметр Accept запроса, чтобы обеспечить обратную совместимость, если это необходимо). - person Rob; 14.11.2013