Не удается обработать успешный ответ 204 и правильно сопоставить ошибочный ответ с помощью RestKit

Я пишу приложение для iOS, которое взаимодействует со службой для обновления профиля пользователя. Чтобы обновить имя пользователя, приложение iOS ПОСТАВЛЯЕТ запрос с телом следующего формата:

 {"name" : {"first" : "FIRSTNAMEGOESHERE", "lastName":"LASTNAMEGOESHERE"}}

В случае, когда тело запроса является действительным (т.е. указаны как имя, так и фамилия), служба возвращает код состояния 204 (Нет содержимого) и пустое тело ответа.

В случае, если тело запроса недействительно (например, отсутствует имя и т. Д.), Служба вернет код состояния 400 и тело ответа в следующем формате:

{"code":"ERRORCODEHERE"}

Приложение iOS использует RestKit, и я не смог понять, как заставить его правильно обрабатывать случаи успеха и неудачи. Если я использую это:

- (void)updateUserName
{
    RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[[NSURL alloc] initWithString:@"http://someqaserver:8080"]];
    [objectManager setRequestSerializationMIMEType:RKMIMETypeJSON];

    RKObjectMapping *userMapping = [RKObjectMapping requestMapping];
    [userMapping addAttributeMappingsFromDictionary:@{@"firstName" : @"first", @"lastName" : @"last"}];

    RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userMapping objectClass:[OurUser class]                                       rootKeyPath:@"name"];

    [objectManager addRequestDescriptor:requestDescriptor];

    [objectManager putObject:[OurUser getCurrentUser]
                   path:@"/mobile/profile/name"
                   parameters:nil
                   success:^(RKObjectRequestOperation *operation, RKMappingResult *result)
                   {
                     NSLog(@"Success!");
                   }
                   failure:^(RKObjectRequestOperation *operation, NSError *error)
                   {
                     NSLog(@"Fail!");
                   }];
}

Очевидно, что это не работает в случае ошибки, но успешно выполняет блок успеха в случае, когда с сервера возвращается 204.

Если я добавлю следующий код перед вызовом putObject, обработка ошибок будет работать, но теперь допустимый случай 204 будет считаться неудачным:

    RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[ServiceError class]];
    [errorMapping addAttributeMappingsFromDictionary:@{@"code" : @"errorCode"}];
    RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
    [objectManager addResponseDescriptor:errorDescriptor];

Кажется, это происходит, поскольку принятые коды состояния HTTP теперь установлены на коды предоставленных дескрипторов ответа, а 204 не является одним из них (или, может быть, это что-то еще?)

Как я могу сделать это так, чтобы: 1.) если возвращено 204, это воспринималось как успех 2.) если возвращалось 4XX, это воспринималось как сбой, а код ошибки был правильно сопоставлен с моим объектом ServiceError?

Заранее благодарим за любую помощь, которую вы можете предоставить.


person Kathleen    schedule 11.03.2013    source источник


Ответы (2)


Проблема была решена путем добавления дескриптора ответа для обработки 204:

RKResponseDescriptor *successResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[RKObjectMapping mappingForClass:nil]
                                                                                               method:RKRequestMethodPUT
                                                                                          pathPattern:nil
                                                                                              keyPath:nil
                                                                                          statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[manager addResponseDescriptor:successResponseDescriptor];
person Kathleen    schedule 11.05.2014

код 204 не является ошибкой, любой статус 2xx считается успешным. 204 означает «нет содержимого», что является совершенно правильным ответом. Если вы ожидаете, что restkit будет рассматривать это как ошибку, убедитесь, что вы выдаете ошибку 3xx, 4xx или 5xx. В вашем случае вы используете RKStatusCodeClassClientErrorm, который предлагает вам выдать ошибку 4xx.

Полный список кодов ошибок см. В wikipedia.

person Kevin R    schedule 25.10.2013
comment
Я думаю, вы неправильно поняли. Я знаю, что 204 - правильный ответ. Проблема заключалась в том, чтобы этот код считал 204 успешным, а также добавлял соответствующий дескриптор ответа, чтобы коды ошибок отображались обратно при получении 400. - person Kathleen; 11.05.2014