RestKit RKObjectMapping列表

时间:2014-01-19 18:51:44

标签: ios objective-c json restkit restkit-0.20

我是RestKit的新手,我正在尝试映射包含我的模型对象数组的json对象。我已调试并发现响应命中我的服务器 - > json回归 - > RestKit说映射是成功的,我有1个对象映射...但是,当我BusinessObjectModel *response = result.array.firstObject;时,errorCode字段和业务数组(bList)都为空 在OnSuccessBlock中。

JSON:

 {
    "bList": 
    [
        {
            "id": 1,
            "name": "aName",
            "owner": 1,
            "category": 1,
        }
        {
            "id": 2,
            "name": "aName2",
            "owner": 1,
            "category": 1,
        }
    ],
    "errorCode": 0
 }

想要将此Json映射到此目标c对象:

BussinessObjectModel对象映射

RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[BusinessObjectModel class]];
[responseMapping addAttributeMappingsFromDictionary:@{
                                                      @"id":   @"business_id",
                                                      @"name":   @"business_name",
                                                      }];


return responseMapping;

BModel:

  @interface bModel : NSObject
    @property (nonatomic, copy) NSNumber *errorCode;
    @property (nonatomic, copy) NSMutableArray *bList;
    +(RKObjectMapping *) getMapping;
    @end

BModel对象映射:

RKObjectMapping *bMapping = [BusinessObjectModel getMapping];

RKObjectMapping *buslstMapping = [RKObjectMapping mappingForClass:[BModel class]];
[buslstMapping addAttributeMappingsFromDictionary:@{@"errorCode":   @"errorCode"}];
// Define the relationship mapping
[buslstMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil
                                                                               toKeyPath:nil
                                                                             withMapping:bussinessMapping]];

return buslstMapping;

描述符如下所示:

 RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:ResponseMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"bList" statusCodes:nil];

修改

我想将上面的Json映射到:

  @interface bModel : NSObject
    @property (nonatomic, copy) NSNumber *errorCode;
    @property (nonatomic, copy) NSMutableArray *bList;
  @end

其中bList是以下对象的数组:

      @interface Business : NSObject
        @property (nonatomic, copy) NSNumber *id;
        @property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSNumber *id;
@property (nonatomic, copy) NSNumber *id;
      @end

我想问题是如何进行嵌套关系(对于上述关系,响应描述符必须是什么)?

3 个答案:

答案 0 :(得分:3)

很高兴看到您使用RestKit。您的第一个帮助程序将是RestKit提供的日志记录。添加这行代码执行AppDelegate并观察控制台是否有错误。

// The * will send everything RestKit does to the console    
// Replace the * with the module you want to check (Network/CoreData/...)
RKLogConfigureByName("RestKit/*", RKLogLevelTrace);

在查看您的JSON时,您希望一方面从keyPath“bList”获取对象,另一方面在出现错误时获取错误代码或消息。 RestKit提供了一个构建错误处理,以从您的JSON中获取该信息。

为RKErrorMessage类初始化RKObjectMapping并使用正确的keyPaths为您的请求添加RKResponseDescriptor,包括状态代码范围(此处使用客户端错误)。 RestKit将自动检测错误代码(在标头内发送时)并应用映射以获取错误消息的内容。

// Init error mapping
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"errorMessage"]];

// Add mapping as response descriptor
RKResponseDescriptor *errorDescriptor = 
[RKResponseDescriptor responseDescriptorWithMapping:errorMapping
                                             method:RKRequestMethodGET
                                        pathPattern:nil                                         
                                            keyPath:@"message" // Edit the keyPath to the value of your JSON (e.g. errorCode)
                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[RKObjectManager.sharedManager addResponseDescriptor:errorDescriptor];

要在发生故障时收到错误消息,您只需获取消息对象即可。使用块获取对象时,可以使用给定NSError中的userInfo字典。

RKErrorMessage *errorMessage = [[error.userInfo objectForKey:RKObjectMapperErrorObjectsKey] firstObject];
NSLog(@"Error: %@", errorMessage);

现在,您可以稍微简化对象模型,并专注于映射BusinessObjectModel。使用字典映射对象时,需要检查本地属性是否与JSON中的值匹配。

RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[BusinessObjectModel class]];
[responseMapping addAttributeMappingsFromDictionary:@
{
    @"value_from_remote_json": @"value_in_local_object", // e.g. @"id" : @"business_id"
    ...
}];
return responseMapping;

您不再需要使用RKRelationshipMapping。重新配置对象/映射,然后重试。日志记录将显示提供的映射以及映射操作是否正常。最后一点,尤其是通过抛出NSAssert错误确保映射在内存中。

RKObjectMapping *bMapping = [BusinessObjectModel getMapping];
NSAssert(bMapping, @"bMapping mapping must not be nil");

修改

要将没有keyPath的值(如“errorCode”字段)映射到对象的映射之外,您需要提供具有相应映射的对象。以documentation为例,您将结束以下内容:

// Init object
@interface RKErrorCode : NSObject
@property (nonatomic) NSNumber *errorCode;
@end

// Init mapping
RKObjectMapping *codeMapping = [RKObjectMapping mappingForClass:[RKErrorCode class]];
[codeMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"errorCode"]];

// Add response descriptor for request
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:codeMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"errorCode" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];

答案 1 :(得分:1)

您的响应描述符不应该有keyPath:@"bList",因为您不想钻取,所以它应设置为nil。

它也不应该根据映射的结构使用ResponseMapping,它应该使用其他映射。

你的映射在这里也是错误的:

@{
     @"business_id":   @"business_id",
     @"business_name":   @"business_name",
 }];

应该是:

@{
     @"id":   @"business_id",
     @"name":   @"business_name",
 }];

因为它指定了JSON名称和核心数据名称。


要解决您的新问题,请回复:

[buslstMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"bList" toKeyPath:@"bList"

而且:

 RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:buslstMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

答案 2 :(得分:1)

找到解决方案,它看起来像这样:

    RKObjectMapping *bModelMapping = [RKObjectMapping mappingForClass:[business class]];
[bModelMapping addAttributeMappingsFromDictionary:@{
                                                      @"id":   @"business_id",
                                                      @"name":   @"business_name",
                                                      }];

    RKObjectMapping *buslstMapping = [RKObjectMapping mappingForClass:[bModel class]];
    [buslstMapping addAttributeMappingsFromDictionary:@{@"errorCode":   @"errorCode"}];
    // Define the relationship mapping
    [buslstMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"bList"
                                                                                   toKeyPath:@"bList"                                                                                bModelMapping]];

    return buslstMapping;

同时更改以下内容:

@property (nonatomic, copy) NSMutableArray *bList; 

@property (nonatomic, retain) NSArray *bList;

这为我提供了一个bModel对象,其中包含一个错误代码值和一个bList,这是一个业务数组,然后可以通过执行以下Business *business = [bModel.blist firstObject];来构建业务