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

时间:2013-11-19 00:36:41

标签: ios objective-c core-data restkit restkit-0.20

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

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

'对于一对一关系的不可接受的价值类型:property =“business”;期望的类型=商业;给定类型=业务;

错误发生在我

之后
  1. 成功发布了一个对象
  2. 成功获得我的反馈JSON
  3. 弹出的错误解析了大部分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。

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

    区别在于“business”。在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配置映射的方式:

     /* ===========================
     * ====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错误。

    非常感谢。

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:0)

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

我用过的东西:

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

我应该使用什么:

[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext

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