使用 Restkit 从 JSON 数组映射关系
Mapping relationships from JSON array with Restkit
我会尽量描述这个问题...
场景
假设我有一个 NSManagedObject 'User'
@class Premise;
@interface User : NSManagedObject
@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *premises;
@end
@interface User (CoreDataGeneratedAccessors)
- (void)addPremisesObject:(Premise *)value;
- (void)removePremisesObject:(Premise *)value;
- (void)addPremises:(NSSet *)values;
- (void)removePremises:(NSSet *)values;
@end
我还有一个 NSManagedObject 'Premise'
@class User;
@interface Premise : NSManagedObject
@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) User *user;
@end
基于它,我正在创建关系路由以将 'Premise' 的 JSON 数组映射到 'User' 对象上的 'premises' 属性。
路线如下:
let getPremisesRoute = RKRoute(relationshipName: "premises",
objectClass: User.self,
pathPattern: "user/:identifier/premises",
method: .GET)
这是 JSON 响应 (/user/1/premises):
[
{
"id": 35,
"name": "Icaraí"
},
{
"id": 32,
"name": "Remanso"
}
]
这是响应描述符:
let getPremisesResponseDescriptor = RKResponseDescriptor(mapping: premiseMapping, method: .GET, pathPattern: "user/:identifier/premises", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful))
这里是'User'和'Premise'
各自的映射
let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: moc)
userMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
userMapping.identificationAttributes = ["identifier"]
userMapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: nil, toKeyPath: "premises", withMapping: premiseMapping))
let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
premiseMapping.identificationAttributes = ["identifier"]
现在我的问题
显然,Restkit 在映射过程中有点混乱。这是请求后的数据库:
用户Table:
前提Table:
请注意,实体之间并未创建关系。
现在,如果我将响应描述符的映射从 premise 更改为 user 映射,数据库将更改为:
用户Table:
前提Table:
我真的很困惑发生了什么,我尝试了很多解决方案都没有成功。
JSON 响应是否异常或我做错了什么? JSON 响应似乎是一种常见的模式,没有关键路径。
您未正确处理映射,或者至少您的映射对于您正在做的事情是错误的。考虑响应是一个用户,但只是一个用户的前提,而不是像现在这样将其视为一个简单的前提列表。然后映射到用户并插入场所。类似于:
RKResponseDescriptor(mapping: userMapping, method: .GET, pathPattern: "user/:identifier/premises", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful))
这里是'User'和'Premise'
各自的映射
let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: moc)
userMapping.addAttributeMappingsFromDictionary(["@metadata.routing.parameters.idEntities":"identifier"])
userMapping.identificationAttributes = ["identifier"]
userMapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: nil, toKeyPath: "premises", withMapping: premiseMapping))
let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
premiseMapping.identificationAttributes = ["identifier"]
你在响应中没有用户名所以你不能映射它,而用户id实际上在请求中所以你需要使用元数据来提取它。
好的,我找到了一个基于@Wain 使用外键的解决方案的可能解决方案。
我向 'Premise' 实体添加了一个新的 属性 'userID' 并使用元数据
将其映射到 URL 上的标识符
let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name", "@metadata.routing.parameters.identifier":"userID"])
然后我在'premiseMapping'
中添加了关系连接
premiseMapping.addConnectionForRelationship("user", connectedBy: ["userID":"identifier"])
如果谁有更优雅的解决方案,请与我们分享。
我会尽量描述这个问题...
场景
假设我有一个 NSManagedObject 'User'
@class Premise;
@interface User : NSManagedObject
@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *premises;
@end
@interface User (CoreDataGeneratedAccessors)
- (void)addPremisesObject:(Premise *)value;
- (void)removePremisesObject:(Premise *)value;
- (void)addPremises:(NSSet *)values;
- (void)removePremises:(NSSet *)values;
@end
我还有一个 NSManagedObject 'Premise'
@class User;
@interface Premise : NSManagedObject
@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) User *user;
@end
基于它,我正在创建关系路由以将 'Premise' 的 JSON 数组映射到 'User' 对象上的 'premises' 属性。
路线如下:
let getPremisesRoute = RKRoute(relationshipName: "premises",
objectClass: User.self,
pathPattern: "user/:identifier/premises",
method: .GET)
这是 JSON 响应 (/user/1/premises):
[
{
"id": 35,
"name": "Icaraí"
},
{
"id": 32,
"name": "Remanso"
}
]
这是响应描述符:
let getPremisesResponseDescriptor = RKResponseDescriptor(mapping: premiseMapping, method: .GET, pathPattern: "user/:identifier/premises", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful))
这里是'User'和'Premise'
各自的映射let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: moc)
userMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
userMapping.identificationAttributes = ["identifier"]
userMapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: nil, toKeyPath: "premises", withMapping: premiseMapping))
let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
premiseMapping.identificationAttributes = ["identifier"]
现在我的问题
显然,Restkit 在映射过程中有点混乱。这是请求后的数据库:
用户Table:
前提Table:
请注意,实体之间并未创建关系。
现在,如果我将响应描述符的映射从 premise 更改为 user 映射,数据库将更改为:
用户Table:
前提Table:
我真的很困惑发生了什么,我尝试了很多解决方案都没有成功。
JSON 响应是否异常或我做错了什么? JSON 响应似乎是一种常见的模式,没有关键路径。
您未正确处理映射,或者至少您的映射对于您正在做的事情是错误的。考虑响应是一个用户,但只是一个用户的前提,而不是像现在这样将其视为一个简单的前提列表。然后映射到用户并插入场所。类似于:
RKResponseDescriptor(mapping: userMapping, method: .GET, pathPattern: "user/:identifier/premises", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful))
这里是'User'和'Premise'
各自的映射let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: moc)
userMapping.addAttributeMappingsFromDictionary(["@metadata.routing.parameters.idEntities":"identifier"])
userMapping.identificationAttributes = ["identifier"]
userMapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: nil, toKeyPath: "premises", withMapping: premiseMapping))
let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name"])
premiseMapping.identificationAttributes = ["identifier"]
你在响应中没有用户名所以你不能映射它,而用户id实际上在请求中所以你需要使用元数据来提取它。
好的,我找到了一个基于@Wain 使用外键的解决方案的可能解决方案。
我向 'Premise' 实体添加了一个新的 属性 'userID' 并使用元数据
将其映射到 URL 上的标识符let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name", "@metadata.routing.parameters.identifier":"userID"])
然后我在'premiseMapping'
中添加了关系连接premiseMapping.addConnectionForRelationship("user", connectedBy: ["userID":"identifier"])
如果谁有更优雅的解决方案,请与我们分享。