Сопоставление JSON с RestKit 0.20.3

Я пытаюсь отобразить объекты через RestKit 0.20.3, но у меня есть эти журналы в течение нескольких дней, знаю:

2013-08-12 18:32:08.158 MyAppIphone[848:5703] E restkit.network:RKResponseMapperOperation.m:304 Failed to parse response data: Loaded an unprocessable response (200) with content type 'application/json'

2013-08-12 18:32:08.174 MyAppIphone[848:5703] E restkit.network:RKObjectRequestOperation.m:238 POST 'myUrl' (200 OK / 0 objects) 

[request=0.1305s mapping=0.0000s total=5.6390s]:
error=Error Domain=org.restkit.RestKit.ErrorDomain Code=-1017 "Loaded an unprocessable response (200) with content type 'application/json'" 

UserInfo=0x1ed5a500 {NSErrorFailingURLKey=myUrl, NSUnderlyingError=0x1ed5b240 "The operation couldn’t be completed. (Cocoa error 3840.)", NSLocalizedDescription=Loaded an unprocessable response (200) with content type 'application/json'}

response.body={"my json content"}

Вот класс MyData:

#import <Foundation/Foundation.h>

@interface MyData : NSObject

@property (nonatomic, retain) NSString *criterias;

@end

Вот как я настроил свой маппер:

- (RKResponseDescriptor*) getDataMapping
{
    // Mapping
    RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[MyData class]];
    [mapping addAttributeMappingsFromDictionary:@{
     @"criteriasHeader":        @"criteriasHeader"
     }];

    // Status code
    NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);

    // Descriptior
    return [RKResponseDescriptor responseDescriptorWithMapping:mapping method:RKRequestMethodPOST pathPattern:nil keyPath:@"regions" statusCodes:statusCodes];
}

Вот моя запрашивающая функция:

- (void) runRequestWithType:(RequestType)type baseUrl:(NSString *)baseUrlString path:(NSString *)path parameters:(NSDictionary *)parameters mapping:(RKResponseDescriptor *) descriptor
{
    // Print heeader and body from the request and the response
    RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
    RKLogConfigureByName("Restkit/Network", RKLogLevelDebug);
    RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
    RKLogConfigureByName("Restkit/ObjectMapping", RKLogLevelDebug);

    // Set up the base url
    NSURL *baseUrl = [NSURL URLWithString:baseUrlString];

    //Run request in block
    RKObjectManager *manager = [RKObjectManager managerWithBaseURL:baseUrl];
    [manager addResponseDescriptorsFromArray:@[descriptor]];

    [manager.router.routeSet addRoute:[RKRoute routeWithClass:[MyData class] pathPattern:path method:RKRequestMethodPOST]];
    //[manager getObjectsAtPath:path parameters:parameters success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    [manager postObject:nil path:path parameters:parameters success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        if ([self.delegate respondsToSelector:@selector(requestDidSucceedWithType:andResponse:)]) {
            [self.delegate requestDidSucceedWithType:type andResponse:[mappingResult firstObject]];
        }
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        if ([self.delegate respondsToSelector:@selector(requestDidFailWithError:andError:)]) {
            [self.delegate requestDidFailWithType:type andError:error];
        }
    }];
}

PS: я пробовал с более коротким JSON, он хорошо работает.

Я сделал что-то неправильно?

Не могли бы вы помочь мне, спасибо.

2 ответа

Эта ошибка возникает из-за отображения JSON в RK. По умолчанию используется NSJSONSerialization, инкапсулированная в RKNSJSONSerialization. Вы можете установить точку останова, чтобы узнать больше об ошибке. Я нашел 2 источника до сих пор:

  • NSJSONSerialization не любит данные не UTF8. Убедитесь, что вы либо получили его с сервера, либо изменили RK, чтобы сделать правильное преобразование из данных в строку (с правильной кодировкой) в UTF8-данные (лучший способ, который я когда-либо имел). Если вы используете CoreData, вы можете посмотреть в RKManagedObjectRequestOperation в строке 586.
  • в iOS5 есть баги. Самый простой способ - использовать другую библиотеку для разбора

Надеюсь, вы сможете изменить кодировку сервера JSON на UTF-8.

Если нет, вы можете решить эту проблему, заменив стандартный обработчик JSON MIME в Restkit. Используйте класс Restkit RKNSJSONSerialization как ссылки.

В пользовательском обработчике MIME-типов JSON выполните преобразование данных из входящей кодировки (в примере ниже ISO-8859-1) в UTF-8, прежде чем выполнять то же самое, что и RKNSJSONSerialization учебный класс.

@implementation MyCustomJSONSerializer    

+ (id)objectFromData:(NSData *)data error:(NSError **)error
{
    NSString* latin = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSISOLatin1StringEncoding];

    NSData* utf8 = [latin dataUsingEncoding:NSUTF8StringEncoding];

    return [NSJSONSerialization JSONObjectWithData:utf8 options:0 error:error];
}

@end

Вы можете сделать подобное для dataFromObject метод, если вы должны отправить данные обратно на сервер в кодировке не-UTF-8.

Теперь вы можете добавить этот пользовательский обработчик после инициализации Restkit, и он будет использоваться вместо стандартного (UTF-8):

[RKMIMETypeSerialization registerClass:[MyCustomJSONSerializer class] forMIMEType:RKMIMETypeJSON];
Другие вопросы по тегам