RestKit:'不可接受的一对一关系值类型:property = "prop";所需类型 = TypeA;给定类型 = TypeA;

Posted

技术标签:

【中文标题】RestKit:\'不可接受的一对一关系值类型:property = "prop";所需类型 = TypeA;给定类型 = TypeA;【英文标题】:RestKit: 'Unacceptable type of value for to-one relationship: property = "prop"; desired type = TypeA; given type = TypeA;RestKit:'不可接受的一对一关系值类型:property = "prop";所需类型 = TypeA;给定类型 = TypeA; 【发布时间】:2013-11-19 00:36:41 【问题描述】:

我正在重构我的应用程序的最新版本以使用 RestKit。

在解析我得到的 JSON 数据时,我遇到了以下错误:

'不可接受的一对一关系值类型:property = “business”;所需类型 = 业务;给定类型 = 业务;

错误发生在我之后

    成功发布了一个对象 成功收到我的反馈 JSON

并且弹出的错误解析了大部分的 JSON 并准备设置 JSON 中传递的对象之间的关系。

我发送的 JSON(这是用于登录):


    "pass":"1234",
    "id":0,
    "login":"awesome_dude",
    "tier":0

我找回的字典:


    business = 2;
    email = "<null>";
    firstName = "<null>";
    id = 36;
    lastName = "<null>";
    login = "<null>";
    pass = "<null>";
    phoneNumber = "<null>";
    sessionId = B0F4E25AF15639D09E49BB9A1F179847;
    tier = 0;

基本上,我只是获得了我的用户 ID、会话 ID 和与我的用户帐户相关联的企业 ID。

但是,User 对象在 CoreData 模型 中的定义略有不同。

区别在于“业务”。在 JSON 通信中,它只是一个业务 ID。但在我的本地 CoreData 模型中,它是与完整 业务对象关系

如果我们在字典中编写CoreData实体定义,它更像是:


    business = 
        address = "addr";
        category = 2;
        email = "company@email.com";
        id = 2;
        name = @"Acme";
        phoneNumber = @"911";
        postalCode = @"98105";
        .........
    

    email = "myemail@company.com";
    firstName = "James";
    id = 36;
    lastName = "Bond";
    login = "awesome_guy";
    pass = "42";
    phoneNumber = "911";
    sessionId = B0F4E25AF15639D09E49BB9A1F179847;
    tier = 0;

因此,这就是我为用户和业务配置映射的方式:

/* ===============================
 * ====Business Object Mapping====
 * ==============================*/

RKEntityMapping* businessObjectMapping = [RKEntityMapping mappingForEntityForName:@"Business" inManagedObjectStore:objectManager.managedObjectStore];

[businessObjectMapping setPerformKeyValueValidation:NO];

NSDictionary *businessObjectMappingDict = @
                                        @"id":@"id",
                                        @"name":@"name",
                                        @"address":@"address",
                                        @"category":@"category",
                                        @"email":@"email",
                                        @"integration":@"integration",
                                        @"phoneNumber":@"phoneNumber",
                                        @"postalCode":@"postalCode",
                                        ;
businessObjectMapping.identificationAttributes = @[@"id"];

[businessObjectMapping addAttributeMappingsFromDictionary:businessObjectMappingDict];

这是我为用户配置映射的方式:

 /* ===========================
 * ====User Object Mapping====
 * ==========================*/

RKEntityMapping* userObjectMapping = [RKEntityMapping mappingForEntityForName:@"User" inManagedObjectStore:objectManager.managedObjectStore];

NSDictionary *userObjectMappingDict = @
                                    @"id":@"id",
                                    @"login":@"login",
                                    @"firstName":@"firstName",
                                    @"lastName":@"lastName",
                                    @"phoneNumber":@"phoneNumber",
                                    @"email":@"email",
                                    @"tier":@"tier",
                                    @"sessionId":@"sessionId",
                                    @"pass":@"password"
                                    ;

userObjectMapping.identificationAttributes = @[@"id"];

[userObjectMapping addAttributeMappingsFromDictionary:userObjectMappingDict];

RKEntityMapping* userBusinessMapping =  [RKEntityMapping mappingForEntityForName:@"Business" inManagedObjectStore:objectManager.managedObjectStore];
[userBusinessMapping addAttributeMappingsFromDictionary:@@"business":@"id"]; // Nil Key path

[userObjectMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"business" withMapping:userBusinessMapping]];

[userObjectMapping setPerformKeyValueValidation:NO];

当然,我已经为通话注册了用户映射:

/*******************************************************************
 * Object Mapping Registration                                     *
 *******************************************************************/

/* Consult API Doc for calls */
// Only used called included

[objectManager addResponseDescriptorsFromArray:@[

......

 [RKResponseDescriptor responseDescriptorWithMapping:userObjectMapping method:RKRequestMethodPOST
                                         pathPattern:@"login" keyPath:nil
                                         statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
......
]];

仅供参考,我正在使用 Mogenerator 来生成 MO 文件,如果这很重要的话。

当然,我已经为实体指定了类。

这个错误基本上是在说“你给了我我想要的,所以你错了”。它看起来更像是 CoreData 错误而不是 RestKit 错误。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

问题在于您提供的 RestKit 映射,因为您试图在一个响应描述符中执行所有操作(将其视为目标是一个数组,而不是关系)。

因此,您需要将映射分解为 2 个响应描述符。 1个用户,1个企业。然后你需要使用外键映射来连接 2 个对象。这意味着将业务 id 作为临时属性添加到用户对象并使用:

[userObjectMapping addConnectionForRelationship:@"business" connectedBy:@ @"businessId": @"businessId" ];

请注意,我指定了businessId,因为您的托管对象不应真正具有id 属性,因此您应更改为userIdbusinessId

【讨论】:

【参考方案2】:

实际上是因为我使用了不正确的 MOC,更具体地说是使用不同的 CoreData 堆栈来插入对象。

我用了什么:

[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]

我应该使用什么:

[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext

使用后者立即解决了问题!

【讨论】:

以上是关于RestKit:'不可接受的一对一关系值类型:property = "prop";所需类型 = TypeA;给定类型 = TypeA;的主要内容,如果未能解决你的问题,请参考以下文章

RestKit 一对多关系逆映射

RestKit 一对多逆向关系(无CoreData)

RESTKit:具有一对多关系的 POST

RestKit嵌套的一对多关系映射很慢

如何使用 RestKit 指定关系?

Restkit + Coredata - 仅将唯一对象添加到一对多关系中