RestKit:为外键关系创build存根

我正在努力映射我的JSON API与RestKit返回的外键关系。

具体来说,我使用Loopback来生成一个API,像TeamUser这样的实体。 有两个terminal默认情况下返回以下JSON:

/团队/

 [ { "title": "Team Title", "id": 1, } ] 

/用户/

 [ { "name": "Alice", "id": 1, "teamId": 1, }, { "name": "Bob", "id": 2, "teamId": 1, }, ... ] 

现在这是一个非常简单的API,对吧? 使用RestKit进行映射应该很容易,但是即使在阅读所有关于该主题的其他问题之后(例如, 寻求有关浅层路由的最佳RestKit / CoreData映射和JSON结构的build议,使用RestKit的 外键关系映射 , Restkit:GET远程链接对象当外键指的是在核心数据中缺less本地对象 ),我只是不知道如何将整个对象图加载到核心数据。

如果它使事情变得简单,我当然也可以改变API。 出于显而易见的原因,我不希望在每个Userembedded整个Team对象,而是使用外键代替。 此外,我想保持端点分开,主要是因为这是Loopback默认生成API的方式。

所以我试着用下面的映射来调用两个Endpoints(按照一个不重要的顺序):

Team映射

 RKEntityMapping *teamMapping = [RKEntityMapping mappingForEntityForName:@"Team" inManagedObjectStore:objectManager.managedObjectStore]; [teamMapping addAttributeMappingsFromArray:@[ @"title", @"id" ]]; teamMapping.identificationAttributes = @[ @"id" ]; [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:teamMapping method:RKRequestMethodAny pathPattern:@"Teams" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 

User映射

 RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:@"User" inManagedObjectStore:objectManager.managedObjectStore]; [userMapping addAttributeMappingsFromArray:@[ @"name", @"id", @"teamId" ]]; userMapping.identificationAttributes = @[ @"id" ]; [userMapping addConnectionForRelationship:@"team" connectedBy:@{ @"teamId": @"id" }]; [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodGET pathPattern:@"Users" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 

正如其他问题(如上面链接的那样)中所build议的,我使用RKConnectionDescription通过瞬态teamId属性build立关系。 映射可以正常工作,JSON有效负载包括TeamUser对象作为数组(在响应描述符中使用keyPath而不是pathPattern),但失败时会使用单独的端点进行调用,而这些端点彼此独立地调用。 在这种情况下,连接关系引用的对象可能尚未创build。 所以为了解决这个问题,应该创build一个Stub对象 ,只有在这种情况下填充id属性。

我怎样才能实现这个RestKit映射?


编辑:如果我将JSON结构从"teamId": 1更改为"team": { "id": 1 }并添加另一个响应描述符与keyPath team吗? 不知道这是否容易做与回环。 什么是最好的方法来做到这一点?


编辑2:所以我添加了以下存根映射:

 RKEntityMapping *teamStubMapping = [RKEntityMapping mappingForEntityForName:@"Team inManagedObjectStore:objectManager.managedObjectStore]; [teamStubMapping addAttributeMappingsFromDictionary:@{@"teamId": @"id"}]; teamStubMapping.identificationAttributes = @[ @"id" ]; [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:teamStubMapping method:RKRequestMethodAny pathPattern:@"Users" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 

当我打开跟踪日志logging,但我没有看到这个映射执行,但。 我究竟做错了什么? 这个映射是否被跳过,因为还有一个已经匹配相同的模式? 当我注释掉User映射时,它完成了它的工作。


编辑3:所以RestKit实际上只使用最后一个响应描述符添加到那些匹配给定的path和相同的键path的对象pipe理器, 这里讨论的GitHub 。 感谢下面的答案,使用nil键path映射解决了这个问题:

 RKEntityMapping *teamStubMapping = [RKEntityMapping mappingForEntityForName:@"Team inManagedObjectStore:objectManager.managedObjectStore]; [teamStubMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"id"]]; teamStubMapping.identificationAttributes = @[ @"id" ]; [objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:teamStubMapping method:RKRequestMethodAny pathPattern:@"Users" keyPath:@"teamId" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; 

我以为我的下面的答案以前的工作,但也许我总是在关于响应描述符完全匹配的评论中偷偷摸摸的问题。

因此,创build另一个映射,但将其设置为无keypath映射,并在@"teamId"的响应描述符上使用@"teamId" 。 这将导致RestKit从响应中提取一个组ID的数组,并将它们作为对象项处理,并分离到用户对象。


JSON很好。 只要创build一个新的响应描述符,它使用了一个teamStubMapping ,这是一个像teamMapping这样的新映射,但是用idreplace了id 。 这个响应描述符的path模式应该是@"Users"

Interesting Posts