Ошибка типа контента AFNetworking версии 2

Я пытаюсь создать приложение для iphone, которое будет взаимодействовать с конкретным сервером JIRA. У меня есть следующий код для входа в систему:

NSURL *url = [[NSURL alloc] initWithString:@"https://mycompany.atlassian.net/rest/auth/latest/session/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSString *postString = [NSString stringWithFormat:@"{\"username\":\"%@\",\"password\":\"%@\"}", username, password];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept" ];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:
    ^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"ERROR: %@", error);

    }
 ];
 [operation start];

Но это дает мне следующую ошибку, связанную с Content-Type:

ERROR: Error Domain=AFNetworkingErrorDomain Code=-1011
"Request failed: unsupported media type (415)"
UserInfo=0x8cd6540
{
  NSErrorFailingURLKey=https://mycompany.atlassian.net/rest/auth/latest/session/,
  NSLocalizedDescription=Request failed: unsupported media type (415),
  NSUnderlyingError=0x8c72e70
  "Request failed: unacceptable content-type: text/html", 

Я не уверен, в чем проблема. Я нашел этот вопрос, который, как мне показалось, может быть похожей проблемой, но в ответах говорится, что нужно использовать AFJSONRequestOperation класс (что я не могу, потому что я использую AFNetworking версии 2, которая не имеет этого класса), или исправить это на стороне сервера (что я также не могу по понятным причинам).

Что я могу исправить эту ошибку, когда я не могу исправить на стороне сервера, и я не могу использовать AFJSONRequestOperation?

5 ответов

Решение

Если вы используете AFNetworking 2.0, вы можете использовать POST метод, который немного упрощает это:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
NSDictionary *parameters = @{@"username":username, @"password":password};
[manager POST:@"https://mycompany.atlassian.net/rest/auth/latest/session/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Это делает создание запроса, устанавливая его Content-Type в соответствии с requestSerializer настройки и кодирует JSON для вас. Одним из преимуществ AFNetworking является то, что вы можете избавиться от сорняков при создании и настройке NSURLRequest объекты вручную.


Кстати, ошибка "Запрос не выполнен: недопустимый тип содержимого: текст /html" означает, что независимо от того, что вы ожидали получить (например, JSON), вы получили HTML-ответ. Это очень часто: многие ошибки сервера (например, сервер сообщает вам, что запрос был искажен и т. Д.) Генерируют сообщения об ошибках HTML. Если вы хотите увидеть этот HTML, в вашем failure блок, просто войдите operation.responseString,

Оказывается, проблема в том, что это одна строка:

[request setValue:@"application/json" forHTTPHeaderField:@"Accept" ];

Должно быть

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type" ];

Ошибка теперь решена. (Изменить: я должен иметь оба, см. Комментарий CouchDeveloper.)

РЕДАКТИРОВАТЬ
Решение Роба лучше, так что я пойду с этим. Я на самом деле пробовал аналогичное решение, что он показывает, но где у него была линия,

manager.requestSerializer = [AFJSONRequestSerializer serializer];

У меня была строка:

[manager.requestSerializer
    setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

... который не работал. Престижность Робу за то, что заставил это работать!

У меня была та же проблема в AFNetworking 2.0, и решение состояло в том, что мне нужно было убедиться, что я установил тип AFHTTPRequestSerializer (в случае, если ваш запрос - JSON), он должен быть таким.

AFHTTPSessionManager *myHTTPManager = ...
[myManager setRequestSerializer:[AFJSONRequestSerializer serializer]];

Вы должны установить оба AFHTTPResponseSerializer а также AFHTTPRequestSerializer

Используйте эту строку кода.

operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

Если вы используете по умолчанию написанный класс AFAppDotNetAPIClient и столкнулись с этой ошибкой. Необходимо добавить responseSerializer. увидеть, что ваш общий метод должен выглядеть так:

+ (instancetype)sharedClient {

static AFAppDotNetAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
    _sharedClient = [[AFAppDotNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:AFAppDotNetAPIBaseURLString]];
    _sharedClient.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    _sharedClient.responseSerializer = [AFHTTPResponseSerializer serializer];
});
return _sharedClient;}
Другие вопросы по тегам