I encountered the same problem myself when i worked with a legacy api. Here are my solutions:
Response json:
{
"resultCode": 0,
"resultDescription": "OK",
"resultContent": [
{
"region_id": 0,
"description": "USA"
},
{
"region_id": 1,
"description": "Europe"
}
]
}
There are two solutions for this problem:
Solution #1: using object mapping with @""
key path
Suppose you already have the managed class Region with attribute names same as json key names
@interface Response
@property (nonatomic) NSInteger resultCode;
@property (nonatomic, strong) NSString resultDescription;
@end
@implementation Response
// Make it KV compliant
@end
Mapping
// Response map
RKObjectMapping* resMap = [RKObjectMapping mappingForClass: [Response class]];
[resMap addAttributeMappingsFromArray: @[@"resultCode", @"resultDescription"]];
responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:resMap method: RKRequestMethodAny pathPattern:@"" keyPath:@"" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
// Region map
RKEntityMapping* mapping = [RKEntityMapping mappingForEntityForName: name inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
[mapping addAttributeMappingsFromArray: @[@"region_id", @"description"]];
descriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping method: RKRequestMethodAny pathPattern:@"/api/regions" keyPath:@"resultContent" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Get the result
Response* res = [[mappingResult dictionary] objectForKey:[NSNull null]];
NSArray* reg = [[mappingResult dictionary] objectForKey:@"resultContent"];
Solution #2: Using serialization
You can register your RKSerialization
implementation
[RKMIMETypeSerialization registerClass:[NKJsonSerialization class]
forMIMEType:RKMIMETypeJSON];
And in your serialization implementation, you can check if response is erroneous response and create a NSError
object then send it back to Restkit.
@implementation NKJsonSerialization
+ (id)objectFromData:(NSData *)data error:(NSError **)error
{
NSError* serializingError = nil;
NSMutableDictionary* jsonObject = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&serializingError];
// Process if there is no error
if (!serializingError)
{
NSString* resCodeStr = [jsonObject objectForKey:@"resultCode"];
if ([resCodeStr intValue] != 0) {
{
// Create your NSError for your domain, contain information about response err
serializingError == <#new created error#>
jsonObject = nil;
}else{
[jsonObject removeObjectForKey: @"resultCode"];
[jsonObject removeObjectForKey: @"resultDescription"];
serializingError = nil;
}
}
*error = serializingError;
return jsonObject;
}
If your response contains erroneous code, In your request callback, RestKit will return a NSError object with underlying error is the error you just created during serialization.
The beauty of this solution is that you dont have to care about mapping response status. The erroneous response will be (should be) handled as an NSError.
And if the json object contains data object at the top level (key path @"") you still can use mapping to obtain it without key conflict as it would happen in solution #1.