【问题标题】:Mapping relationships from JSON array with Restkit使用 Restkit 从 JSON 数组映射关系
【发布时间】:2015-09-08 08:43:15
【问题描述】:

我会尽量描述这个问题...

场景

假设我有一个 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 '前提'

@class User;

@interface Premise : NSManagedObject

@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) User *user;

@end

基于此,我正在创建一个关系路由,以将“前提”的 JSON 数组映射到“用户”对象上的“前提”属性。

路线如下:

 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 在映射过程中变得有点混乱。这是请求后的数据库:

用户表:

前提表:

请注意,实体之间并未创建关系。

现在,如果我将响应描述符的映射从 前提 更改为 user 映射,数据库将更改为:

用户表:

前提表:

我真的对发生的事情感到困惑,我尝试了很多解决方案都没有成功。

是 JSON 响应不正常还是我做错了什么? JSON 响应似乎是一种通用模式,具有 nil 键路径。

【问题讨论】:

    标签: ios json swift restkit restkit-0.20


    【解决方案1】:

    您正在错误地接近映射,或者至少您的映射对于您正在做的事情是错误的。考虑响应是用户,但只是用户的前提,而不是像现在这样将其视为简单的前提列表。然后映射到用户并插入场所。比如:

    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 实际上在请求中,因此您需要使用元数据来提取它。

    【讨论】:

    • 我得到了元数据部分,但这个解决方案带来了另一个问题。如果我按照您的建议更改“用户”映射,当我从服务器请求我的用户对象(例如登录)时,Restkit 不会将作为 JSON 传递的“id”属性映射到“标识符”,相反,它会查找元数据但不会找到它,因此将 'id' 等同于 'nil'。我是否必须为“用户”实体创建多个映射?
    • 使用这种方法你有多个映射,是的。对此没有任何限制。
    【解决方案2】:

    好的,我找到了一个基于@Wain 使用外键的解决方案的可能解决方案。

    我向“Premise”实体添加了一个新属性“userID”,并使用元数据将其映射到 URL 上的标识符

    let premiseMapping = RKEntityMapping(forEntityForName: "Premise", inManagedObjectStore: moc)
    
     premiseMapping.addAttributeMappingsFromDictionary(["id":"identifier", "name":"name", "@metadata.routing.parameters.identifier":"userID"])
    

    然后我向“前提映射”添加了关系连接

    premiseMapping.addConnectionForRelationship("user", connectedBy: ["userID":"identifier"])
    

    如果有人有更优雅的解决方案,请与我们分享。

    【讨论】:

    • 这通常是另一个选项(您可以从 2 个端配置关系,这是实现此目的的 2 种技术......)
    猜你喜欢
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多