Objective c RestKit嵌套关系

Objective c RestKit嵌套关系,objective-c,core-data,restkit,restkit-0.20,Objective C,Core Data,Restkit,Restkit 0.20,使用RestKit,我试图映射以下JSON { "userID": 1, "collections": [ { "collectionID": 120, "friends": [ { "friendID": 6, "orders": [ { "orderID": 1, "name": "Small"

使用RestKit,我试图映射以下JSON

{
  "userID": 1,
  "collections": [
    {
      "collectionID": 120,
      "friends": [
        {
          "friendID": 6,
          "orders": [
            {
              "orderID": 1,
              "name": "Small"
            }
          ]
        }
      ]
    },
    {
      "collectionID": 123,
      "friends": [
        {
          "friendID": 6,
          "orders": [
            {
              "orderID": 2,
              "name": "Medium"
            }
          ]
        }
      ]
    }
  ]
}
我正在使用RestKit和MagicalRecord-下面的设置代码、映射和关系

NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"]];
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"db.sqlite"];

[managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:nil];
[managedObjectStore createManagedObjectContexts];

// Configure MagicalRecord to use RestKit's Core Data stack
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:managedObjectStore.persistentStoreCoordinator];
[NSManagedObjectContext MR_setRootSavingContext:managedObjectStore.persistentStoreManagedObjectContext];
[NSManagedObjectContext MR_setDefaultContext:managedObjectStore.mainQueueManagedObjectContext];

RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://127.0.0.1:3500"]];
objectManager.managedObjectStore = managedObjectStore;

RKEntityMapping *appMapping = [RKEntityMapping mappingForEntityForName:@"App" inManagedObjectStore:managedObjectStore];
appMapping.identificationAttributes = @[ @"userID" ];

RKEntityMapping *collectionMapping = [RKEntityMapping mappingForEntityForName:@"Collection" inManagedObjectStore:managedObjectStore];
collectionMapping.identificationAttributes = @[ @"collectionID" ];
[collectionMapping addAttributeMappingsFromArray:@[@"collectionID"]];

RKEntityMapping *friendMapping = [RKEntityMapping mappingForEntityForName:@"Friend" inManagedObjectStore:managedObjectStore];
friendMapping.identificationAttributes = @[ @"friendID" ];
[friendMapping addAttributeMappingsFromArray:@[@"friendID"]];

RKEntityMapping *orderMapping = [RKEntityMapping mappingForEntityForName:@"Order" inManagedObjectStore:managedObjectStore];
orderMapping.identificationAttributes = @[ @"orderID" ];
[orderMapping addAttributeMappingsFromArray:@[@"orderID", @"name"]];


RKRelationshipMapping *appCollectionRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:@"collections" toKeyPath:@"collections" withMapping:collectionMapping];
[appMapping addPropertyMapping:appCollectionRelationship];

RKRelationshipMapping *collectionFriendRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:@"friends" toKeyPath:@"friends" withMapping:friendMapping];
[collectionMapping addPropertyMapping:collectionFriendRelationship];

RKRelationshipMapping *friendsOrderRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:@"orders" toKeyPath:@"orders" withMapping:orderMapping];
[friendsOrderRelationship setAssignmentPolicy:RKUnionAssignmentPolicy];
[friendMapping addPropertyMapping:friendsOrderRelationship];
然后,在我的API(上面输出JSON块)上用下面的控制台查询/test路由

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

[objectManager getObjectsAtPath:@"/test" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {

    App *app = [mappingResult firstObject];
    for (Collection *collection in app.collections) {
        NSLog(@"collectionID = %@", collection.collectionID);
        for (Friend *friend in collection.friends) {
            NSLog(@"friendID = %@", friend.friendID);
            for (Order *order in friend.orders) {
                NSLog(@"Name = %@", order.name);
            }
        }
    }
} failure:^(RKObjectRequestOperation *operation, NSError *error) {}];
提供以下输出-请注意,两个名称都是中名称,而不是一个小名称和另一个中名称

collectionID = 120
friendID = 6
Name = Medium
Name = Small
collectionID = 123
friendID = 6
Name = Medium
Name = Small

为什么会发生这种情况?我猜这是因为两个好友ID都是相同的,即使它们在不同的集合中…

这是因为您有
identificationAttributes=@[@“friendID”]和关系的默认关系连接规则,而不是替换。因此,第二个映射找到由第一个映射创建的朋友,并替换订单关系内容

您无法根据显示的JSON实际更改唯一标识符,但您可能希望检查它(与您的对象图需求相关)


另外/或者,有关如何更改关系分配策略以避免丢失原始关系内容的详细信息,请参阅。

谢谢您的输入!因此,我应该删除
friendMapping.identificationAttributes
,并将当前关系代码更改为
RKRelationshipMapping*CollectionFriendmapping=[RKRelationshipMappingFromKeyPath:@“friends”tokePath:@“friends”with Mapping:orderMapping];[collectionFriendRelationship setAssignmentPolicy:RKUnionAssignmentPolicy]我甚至不知道分配政策<代码>分配策略< /代码>更改本身就足够了,它取决于模型中您想要的对象,您认为是一个复制品……这是否意味着它将结合两个(潜在的)更多名称项目?请参阅已编辑的代码(仅底部的关系)是的,这就是为什么您需要决定所需内容,union/“duplicates”Hmmm-这两个选项都没有多大用处,因为我只需要一个名称(在其他属性中-这只是一个简化的用例)。我想我可能会考虑从Friend对象中提取订单,然后创建一个指向该朋友对应订单的索引。除非我遗漏了什么?谢谢:)