在这里他们似乎做了一个解决方法: Relationship between RKObjectMapping and RKEntityMapping
我可以将它们混合而不做任何解决方法吗? 感谢。
编辑:这里我添加一个示例JSON。我想要存储在Core Data中的是两个实体Region,但没有关于resultCode或resultDescription的内容。这就是我问我是否可以混合它们的原因。
{
"resultCode": 0,
"resultDescription": "OK",
"resultContent": [
{
"region_id": 0,
"description": "USA"
},
{
"region_id": 1,
"description": "Europe"
}
]
}
答案 0 :(得分:1)
我不确定你究竟在问什么... RKEntityMapping用于映射到Core Data实体,而RKObjectMapping用于映射到常规对象表示。所以问题可能是,您是否正在使用Core Data?
答案 1 :(得分:1)
您需要为RKObjectMapping&定义两个单独的描述符。 RKEntityMapping对象,在你的情况下为StatusMapping& RegionMapping然后将它们添加到ObjectManager,它就像魅力(我给你的示例代码和类来实现这一点):
像这样定义ResponseStatus类:
// ...
ResponseStatus.h
// ...
@interface ResponseStatus : NSObject
@property (nonatomic) BOOL resultCode;
@property (nonatomic, strong) NSString *resultDescription;
+ (RKObjectMapping *)rkObjectMappingForResponse:(BOOL)includeAll;
+ (RKObjectMapping *)rkObjectMappingForRequest:(BOOL)includeAll;
+ (NSDictionary *)rkAttributeMappingsDictionary:(BOOL)request includeAll:(BOOL)includeAll;
@end
// ...
ResponseStatus.m
// ...
@implementation ResponseStatus
+ (RKObjectMapping *)rkObjectMappingForResponse:(BOOL)includeAll {
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[ResponseStatus class]];
[mapping addAttributeMappingsFromDictionary:[self rkAttributeMappingsDictionary:NO includeAll:includeAll]];
if (includeAll) {
}
return mapping;
}
+ (RKObjectMapping *)rkObjectMappingForRequest:(BOOL)includeAll {
RKObjectMapping *mapping = [RKObjectMapping requestMapping];
[mapping addAttributeMappingsFromDictionary:[self rkAttributeMappingsDictionary:YES includeAll:includeAll]];
if (includeAll) {
}
return mapping;
}
+ (NSDictionary *)rkAttributeMappingsDictionary:(BOOL)request includeAll:(BOOL)includeAll {
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
if (includeAll) {
[dic addEntriesFromDictionary:@{
@"resultCode": @"resultCode",
@"resultDescription": @"resultDescription",
}];
}
return dic;
}
@end
为ResponseStatus定义描述符映射(结果)
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *statusResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[ResponseStatus rkObjectMappingForResponse:YES] method:RKRequestMethodAny pathPattern:nil keyPath:@"" statusCodes:statusCodes];
为RKEntityMapping定义描述符映射
RKResponseDescriptor *gameResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[Game rkEntityMappingForResponse:YES] method:RKRequestMethodAny pathPattern:nil keyPath:@"games" statusCodes:statusCodes];
向objectManager添加响应描述符
[objectManager addResponseDescriptorsFromArray:@[gameResponseDescriptor, statusResponseDescriptor]];
这是处理映射结果的方法
RKObjectRequestOperation *operation = [objectManager managedObjectRequestOperationWithRequest:requestObject managedObjectContext:managedObjectContext success: ^(RKObjectRequestOperation *operation, RKMappingResult *result) {
if ([RKUtils isResponseStatusError:[result array]])
{
//..
}
} failure: ^(RKObjectRequestOperation *operation, NSError *error)
{
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
+ (BOOL)isResponseStatusError:(NSArray *)itemsList {
if ([itemsList count] != 1) {
return NO;
}
id object = itemsList[0];
if ([object isKindOfClass:[ResponseStatus class]]) {
ResponseStatus *responseStatus = object;
if (!responseStatus.resultCode) {
NSLog(@"Error : %@", responseStatus.message);
return YES;
}
}
return NO;
}
并打个电话,希望有所帮助。
答案 2 :(得分:1)
在这种情况下,您无需混合它们。创建响应描述符时,将关键路径设置为resultContent
,并使用实体映射。
可以在某些方面混合映射类型,但这通常需要根据具体情况进行考虑。通常,您将使用多个响应描述符来保持映射分离,然后将结果组合为后期处理。
答案 3 :(得分:1)
当我使用遗留API时,我自己遇到了同样的问题。以下是我的解决方案:
回应json:
{
"resultCode": 0,
"resultDescription": "OK",
"resultContent": [
{
"region_id": 0,
"description": "USA"
},
{
"region_id": 1,
"description": "Europe"
}
]
}
此问题有两种解决方案:
@""
密钥路径的对象映射假设您已经拥有属性名称与json密钥名称相同的托管类Region
@interface Response
@property (nonatomic) NSInteger resultCode;
@property (nonatomic, strong) NSString resultDescription;
@end
@implementation Response
// Make it KV compliant
@end
映射
// 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)];
获取结果
Response* res = [[mappingResult dictionary] objectForKey:[NSNull null]];
NSArray* reg = [[mappingResult dictionary] objectForKey:@"resultContent"];
您可以注册RKSerialization
实施
[RKMIMETypeSerialization registerClass:[NKJsonSerialization class]
forMIMEType:RKMIMETypeJSON];
在序列化实现中,您可以检查响应是否是错误的响应,并创建一个NSError
对象,然后将其发送回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;
}
如果您的响应包含错误的代码,在您的请求回调中,RestKit将返回一个带有基础错误的NSError对象,即您在序列化过程中刚刚创建的错误。
此解决方案的优点在于您无需关心映射响应状态。错误的响应将(应该)作为NSError处理。
如果json对象包含顶级数据对象(关键路径@“”),您仍然可以使用映射来获取它,而不会发生关键冲突,就像在解决方案#1中一样。
答案 4 :(得分:0)
好的,经过几次测试后,我意识到RestKit将RKEntityMapping保存在核心数据中,而不是RKObjectMapping。它完美地运作。我喜欢RestKit :))