问题
I'm trying to map objects through RestKit 0.20.3, but I'm having those logs for days know:
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"}
Here is MyData class:
#import <Foundation/Foundation.h>
@interface MyData : NSObject
@property (nonatomic, retain) NSString *criterias;
@end
Here is how I set up my mapper:
- (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];
}
Here my requesting 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: I tried with a shorter JSON, it works well.
Did I do something wrong?
Could you help me, thanks.
回答1:
This kind of error comes from JSON mapping under RK. Default is to use NSJSONSerialization encapsulated in RKNSJSONSerialization. You can put a breakpoint there to find out maybe more about the error. I found 2 sources until now:
- NSJSONSerialization doesn't like non UTF8 data. Make sure you either receive it from server, or modify RK to do the proper conversion from data to string(with correct encoding) to UTF8-data(best way i have so far). If using CoreData you can look in RKManagedObjectRequestOperation at line 586.
- in iOS5 there are bugs. Easiest fix is to use another parsing library
回答2:
Hopefully you are able to change the server encoding of the JSON to UTF-8.
If not, you can resolve this issue by replacing the default JSON mime type handler in Restkit. Use the Restkit class RKNSJSONSerialization
as reference.
In your custom JSON mime type handler, perform data conversion from the incoming encoding (in the example below ISO-8859-1) to UTF-8, before doing the same as the RKNSJSONSerialization
class.
@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
You can do similar for the dataFromObject
method if you must POST data back to the server in non-UTF-8 encoding.
You can now add this custom handler after you init Restkit, and it will be used vs the default (UTF-8) one:
[RKMIMETypeSerialization registerClass:[MyCustomJSONSerializer class] forMIMEType:RKMIMETypeJSON];
来源:https://stackoverflow.com/questions/18192522/mapping-json-with-restkit-0-20-3