使用RestKit 0.20.3来映射json

我试图映射对象通过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]; } 

在这里我的请求function:

 - (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尝试过,效果很好。

我做错什么了吗?

你能帮我吗,谢谢。

这种错误来自RK下的JSON映射。 默认是使用封装在RKNSJSONSerialization中的NSJSONSerialization。 你可以在那里放置一个断点来找出更多关于错误的信息。 直到现在我发现了两个来源:

  • NSJSONSerialization不喜欢非UTF8数据。 确保你要么从服务器接收它,要么修改RK以正确地将数据转换为string(使用正确的编码)转换为UTF8数据(到目前为止我已经有了最好的方法)。 如果使用CoreData,则可以在第586行查看RKManagedObjectRequestOperation。
  • 在iOS5中有错误。 最简单的解决方法是使用另一个parsing库

希望您能够将JSON的服务器编码更改为UTF-8。

如果没有,您可以通过replaceRestkit中的默认JSON MIMEtypes处理程序来解决此问题。 使用Restkit类RKNSJSONSerialization作为参考。

在您的自定义JSON MIMEtypes处理程序中,在执行与RKNSJSONSerialization类相同的RKNSJSONSerialization之前,将传入编码(在下面的示例中为ISO-8859-1)执行数据转换为UTF-8。

 @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 

如果您必须以非UTF-8编码将数据发送回服务器, dataFromObject方法执行类似的dataFromObject

您现在可以初始化Restkit 之后添加此自定义处理程序,并将其用于默认(UTF-8)之一:

 [RKMIMETypeSerialization registerClass:[MyCustomJSONSerializer class] forMIMEType:RKMIMETypeJSON];