Restkit JSON сообщение об ошибке с сервера - PullRequest
14 голосов
/ 23 марта 2012

Я потратил много часов на решение этой проблемы.Я использую Restkit 0.9.3 с Object Mapping 2.0.Все данные в формате JSON.Я могу правильно выполнять операции GET, POST, PUT и DELETE, это тело ответа, которое я не улавливаю и правильно отображаю ..

Так что моя проблема в том, что мой restful api возвращает ошибки, когда что-то идет не так.Я хочу отобразить эти ошибки с помощью restkit, fx эта ошибка возвращается:

{"code": "401", "message": "Unauthorized"}

Как мне правильно отобразить этот json? Я много чего перепробовал и мог бы использовать некоторые рекомендации - или приведите пример этого.

Ответы [ 4 ]

29 голосов
/ 31 мая 2013

Для RestKit v0.20

при условии, что ваше тело HTTP:

{"error": "..."}

вы создаете отображение и дескриптор:

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];

[errorMapping addPropertyMapping: [RKAttributeMapping attributeMappingFromKeyPath:@"error" toKeyPath:@"errorMessage"]];
RKResponseDescriptor *errorResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[objectManager addResponseDescriptor:errorResponseDescriptor];

и затем вы можете получить к нему доступ из блока сбоев:

failure:^(RKObjectRequestOperation *operation, NSError *error) {
                NSLog(@"errorMessage: %@", [[error userInfo] objectForKey:RKObjectMapperErrorObjectsKey]);
            }

Здесь используется встроенный класс RKErrorMessage, хотя вы можете создать свой собственный класс с дополнительными полями.

10 голосов
/ 15 мая 2012

Для версии 0.10.0 эта ошибка ответа может быть отображена следующим образом:

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
[errorMapping mapKeyPath:@"message" toAttribute:@"errorMessage"];
[[[RKObjectManager sharedManager] mappingProvider] setErrorMapping:errorMapping];

Запросы, возвращающие ошибку, вызовут следующий метод делегата:

- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error {
    NSArray *errorMessages = [[error userInfo] objectForKey:RKObjectMapperErrorObjectsKey];
    RKErrorMessage *errorMessage = [errorMessages objectAtIndex:0]; // First and only object in your case.
    NSString *message = [errorMessage errorMessage];
    NSInteger code = [[objectLoader response] statusCode];
    NSLog(@"ERROR: [%d] %@", code, message); // => ERROR: [401] Unauthorized
}
5 голосов
/ 15 мая 2015

Используя Restkit v0.2x , вы можете сопоставить все атрибуты JSON, которые вы хотите, с уже существующим RKErrorMessage.userInfo Свойством словаря следующим образом [ Swift ]:

let errorMapping = RKObjectMapping(forClass: RKErrorMessage.self);
errorMapping.addPropertyMapping(RKAttributeMapping(fromKeyPath: nil, toKeyPath: "userInfo"));

let errorResponseDescriptor = RKResponseDescriptor(
    mapping: errorMapping,
    method: RKRequestMethod.Any,
    pathPattern: nil,
    keyPath: "error", //or nil, according to your json response
    statusCodes: RKStatusCodeIndexSetForClass(UInt(RKStatusCodeClassClientError)))
);

Итак, вы можете отобразить ответ JSON с ошибкой, подобный этому:

{
    "error": {
        "message": "Error message",
        "cause": "...",
        "code": "my_error_code",
        "url": "..."
        ...
    }
}

И получить RKErrorMessage со всеми атрибутами в закрытии failure следующим образом:

failure: { (operation, error) -> Void in
    if let errorMessage = error.userInfo?[RKObjectMapperErrorObjectsKey]?.firstObject as? RKErrorMessage{
        let message = errorMessage.userInfo["message"] as! String;
        let code = errorMessage.userInfo["code"] as! String;
        ...
    }
}

Надеюсь, это кому-нибудь пригодится!

0 голосов
/ 23 марта 2012

если объект возвращается, ваш делегат должен вызвать этот метод:

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {}

в этом методе вы должны вызывать экземпляр вашего класса «error» и отображать «code» и «message» при необходимости.

Более простой способ обработки ошибок - использовать:

- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {

if(objectLoader.response.statusCode == 401)
{ ...

И показать необходимое сообщение об ошибке в этом методе.

...