RestKit 0.24 映射使用 addConnectionForRelationship

RestKit 0.24 mapping using addConnectionForRelationship

这几天我都在为这段关系苦苦挣扎。

数据模型

我有以下 json:

{
"response":{
"pageInfo":[
],
"threads":{
"userId":"1",
"threadId":"58",
"status":"",
"timestamp":"2015-02-03T13:24:29.000Z",
"messages":[
{
"messageId":"23",
"threadId":"58",
"participantId":"106",
"text":"test",
"status":"",
"timestamp":"2015-02-03 13:24:29"
}
],
"participants":[
{
"participantId":"106",
"threadId":"58",
"userId":"1",
"user":{
"id":"1",
"username":"admin",
"email":"admin@go-surfin.com",
"medias":[
{
"id":"181",
"userId":"1",
"serviceName":"surfin",
"serviceURL":"http:\/\/media.go-surfin.com\/",
"mimeType":"image\/jpeg",
"size":"43505",
"width":"480",
"height":"320",
"filename":"c5564a10-f950-4398-a655-c9b31a0e8500.jpeg",
"url":"uploads\/avatar\/c5564a10-f950-4398-a655-c9b31a0e8500.jpeg",
"name":"",
"type":"AVATAR",
"status":"APPROUVED",
"comments":[
],
"likeIds":[
],
"timestamp":"2015-01-28T07:53:03.000Z"
}
],
"stats":{
"userId":"1",
"followers":2,
"followings":3,
"medias":3,
"trips":0,
"spots":506
},
"profile":{
"country":"FR",
"type":"SURFER",
"pro":"0"
},
"social":{
"facebook":"",
"youtube":"",
"twitter":"",
"instagram":""
},
"created":"2014-09-10T11:05:08.000Z",
"followingIds":[
"23",
"19",
"3"
],
"settings":[
{
"id":"17",
"userId":"1",
"type":"notifications",
"key":"notifications.newspot",
"value":"0",
"timestamp":"2014-11-12T16:52:20.000Z"
},
{
"id":"18",
"userId":"1",
"type":"notifications",
"key":"notifications.newcontest",
"value":"0",
"timestamp":"2014-11-05T15:56:22.000Z"
},
{
"id":"19",
"userId":"1",
"type":"notifications",
"key":"notifications.newmessage",
"value":"0",
"timestamp":"2014-11-04T09:14:29.000Z"
},
{
"id":"20",
"userId":"1",
"type":"metrics",
"key":"metrics.speed",
"value":"0",
"timestamp":"2015-01-25T17:57:31.000Z"
},
{
"id":"22",
"userId":"1",
"type":"metrics",
"key":"metrics.distance",
"value":"0",
"timestamp":"2014-11-30T11:17:31.000Z"
},
{
"id":"23",
"userId":"1",
"type":"metrics",
"key":"metrics.length",
"value":"0",
"timestamp":"2014-11-08T09:40:07.000Z"
},
{
"id":"24",
"userId":"1",
"type":"metrics",
"key":"metrics.forecast",
"value":"0",
"timestamp":"2014-11-30T11:17:31.000Z"
},
{
"id":"25",
"userId":"1",
"type":"notifications",
"key":"notifications.commentspot",
"value":"0",
"timestamp":"2014-11-12T16:52:20.000Z"
},
{
"id":"26",
"userId":"1",
"type":"notifications",
"key":"notifications.newplace",
"value":"1",
"timestamp":"2014-12-10T13:06:38.000Z"
},
{
"id":"27",
"userId":"1",
"type":"notifications",
"key":"notifications.mediaplace",
"value":"1",
"timestamp":"2014-12-10T17:37:30.000Z"
},
{
"id":"28",
"userId":"1",
"type":"notifications",
"key":"notifications.mediacontest",
"value":"1",
"timestamp":"2014-12-10T17:37:46.000Z"
},
{
"id":"30",
"userId":"1",
"type":"notifications",
"key":"notifications.mediaspot",
"value":"1",
"timestamp":"2014-12-11T08:41:50.000Z"
},
{
"id":"31",
"userId":"1",
"type":"notifications",
"key":"notifications.newtrip",
"value":"1",
"timestamp":"2015-01-16T14:13:37.000Z"
},
{
"id":"32",
"userId":"1",
"type":"notifications",
"key":"notifications.mediatrip",
"value":"1",
"timestamp":"2014-12-11T08:53:17.000Z"
},
{
"id":"33",
"userId":"1",
"type":"notifications",
"key":"notifications.jointrip",
"value":"1",
"timestamp":"2014-12-11T08:54:42.000Z"
},
{
"id":"36",
"userId":"1",
"type":"notifications",
"key":"notifications.commentplace",
"value":"1",
"timestamp":"2015-01-31T17:26:22.000Z"
}
],
"favorites":{
"userId":"1",
"placeIds":[
],
"spotIds":[
"4698"
],
"contestIds":[
],
"tripIds":[
]
},
"likes":{
"userId":"1",
"placeIds":[
],
"spotIds":[
],
"contestIds":[
],
"tripIds":[
],
"feedbackIds":[
],
"mediaIds":[
],
"statusIds":[
]
}
},
"status":"CREATOR",
"timestamp":"2015-02-03 13:20:33"
},
{
"participantId":"107",
"threadId":"58",
"userId":"2",
"user":{
"id":"2",
"username":"lgriffie",
"email":"lgriffie@go-surfin.com",
"medias":[
{
"id":"179",
"userId":"2",
"serviceName":"surfin",
"serviceURL":"http:\/\/media.go-surfin.com\/",
"mimeType":"image\/jpeg",
"size":"18808",
"width":"212",
"height":"212",
"filename":"a0de6758-97ac-4b84-9fae-e33b614640f0.jpeg",
"url":"uploads\/avatar\/a0de6758-97ac-4b84-9fae-e33b614640f0.jpeg",
"name":"",
"type":"AVATAR",
"status":"APPROUVED",
"comments":[
],
"likeIds":[
],
"timestamp":"2014-09-10T19:27:05.000Z"
}
],
"stats":{
"userId":"2",
"followers":1,
"followings":2,
"medias":1,
"trips":0,
"spots":0
},
"profile":{
"country":"US",
"type":"FOLLOWER",
"pro":"0"
},
"social":{
"facebook":"",
"youtube":"",
"twitter":"",
"instagram":""
},
"created":"2014-09-10T19:27:05.000Z",
"followingIds":[
"3",
"1"
]
},
"status":"NORMAL",
"timestamp":"2015-02-03 13:20:33"
}
],
"setting":{
"settingId":"7",
"threadId":"58",
"notification":"0",
"block":"0",
"timestamp":"2015-02-03 13:20:33"
}
},
"apiMethod":"threads:new"
}
}

这是为每个实体定义的映射

线程

+ (RKEntityMapping *)mapping
{
    RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:[self entityName]
                                                     inManagedObjectStore:[RKManagedObjectStore defaultStore]];

[entityMapping addAttributeMappingsFromDictionary:@{
                                                    @"threadId":           @"threadId",
                                                    @"userId":             @"userId",
                                                    @"status":             @"status",
                                                    @"timestamp":          @"timestamp"
                                                    }];
entityMapping.identificationAttributes = @[ @"threadId" ];

[entityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"messages" toKeyPath:@"messages" withMapping:[AOThreadMessage mapping]]];
[entityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"participants" toKeyPath:@"participants" withMapping:[AOThreadParticipant mapping]]];
[entityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"setting" toKeyPath:@"setting" withMapping:[AOThreadSetting mapping]]];

[entityMapping addConnectionForRelationship:@"user" connectedBy:@{ @"userId": @"userId" }];

[entityMapping setAssignsDefaultValueForMissingAttributes:YES];

return entityMapping;
}

+ (RKResponseDescriptor *)responseDescriptor
{
    return [RKResponseDescriptor responseDescriptorWithMapping:[AOThread mapping]
                                                        method:RKRequestMethodPOST | RKRequestMethodGET
                                                   pathPattern:nil
                                                       keyPath:@"response.threads"
                                                   statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
}

线程消息

+ (RKEntityMapping *)mapping
{
    RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:[self entityName]
                                                     inManagedObjectStore:[RKManagedObjectStore defaultStore]];

[entityMapping addAttributeMappingsFromDictionary:@{
                                                    @"messageId":          @"messageId",
                                                    @"participantId":      @"participantId",
                                                    @"text":               @"text",
                                                    @"status":             @"status",
                                                    @"timestamp":          @"timestamp"
                                                    }];
entityMapping.identificationAttributes = @[ @"messageId" ];

[entityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"media" toKeyPath:@"media" withMapping:[AOMedia mapping]]];

[entityMapping setAssignsDefaultValueForMissingAttributes:YES];

return entityMapping;
}

+ (RKResponseDescriptor *)responseDescriptor
{
    return [RKResponseDescriptor responseDescriptorWithMapping:[AOThreadMessage mapping]
                                                        method:RKRequestMethodPOST | RKRequestMethodGET
                                                   pathPattern:nil
                                                       keyPath:@"response.messages"
                                                   statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
}

线程参与者

+ (RKEntityMapping *)mapping
{
    RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:[self entityName]
                                                     inManagedObjectStore:[RKManagedObjectStore defaultStore]];

[entityMapping addAttributeMappingsFromDictionary:@{
                                                    @"participantId":      @"participantId",
                                                    @"userId":             @"userId",
                                                    @"status":             @"status",
                                                    @"timestamp":          @"timestamp"
                                                    }];
entityMapping.identificationAttributes = @[ @"participantId" ];

[entityMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"user" toKeyPath:@"user" withMapping:[AOUser mapping]]];

[entityMapping setAssignsDefaultValueForMissingAttributes:YES];

return entityMapping;
}

+ (RKResponseDescriptor *)responseDescriptor
{
    return [RKResponseDescriptor responseDescriptorWithMapping:[AOThreadParticipant mapping]
                                                        method:RKRequestMethodPOST | RKRequestMethodGET
                                                   pathPattern:nil
                                                       keyPath:@"response.participants"
                                                   statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
}

线程设置

+ (RKEntityMapping *)mapping
{
    RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:[self entityName]
                                                     inManagedObjectStore:[RKManagedObjectStore defaultStore]];

[entityMapping addAttributeMappingsFromDictionary:@{
                                                    @"settingId":          @"settingId",
                                                    @"notification":       @"notification",
                                                    @"block":              @"block",
                                                    @"timestamp":          @"timestamp"
                                                    }];
entityMapping.identificationAttributes = @[ @"settingId" ];

[entityMapping setAssignsDefaultValueForMissingAttributes:YES];

return entityMapping;
}

+ (RKResponseDescriptor *)responseDescriptor
{
    return [RKResponseDescriptor responseDescriptorWithMapping:[AOThreadSetting mapping]
                                                        method:RKRequestMethodPOST | RKRequestMethodGET
                                                   pathPattern:nil
                                                       keyPath:@"response.setting"
                                                   statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
}

AOThreadMessage线程关系为nil。其他关系设置正确。

<AOThreadMessage: 0x7fa529a694d0> (entity: AOThreadMessage; id: 
0xd00000000004001c <x-coredata://23C60BAE-57BD-4904-BF7B-7D550DE13190/AOThreadMessage/p1> ; data: {
    address = nil;
    media = nil;
    messageId = 20;
    participantId = 106;
    status = "";
    text = test;
    thread = nil;
    timestamp = "2015-02-03 13:20:33 +0000";
})

想看完整RestKit数据映射日志的小伙伴,点这里http://cloud.appsido.com/qN

您的 JSON 包含一切,因此您不需要外键映射。事实上,拥有它们可能会导致您的问题,并导致实际上只有最后一项被添加到关系中(因为默认是替换而不是联合)。因此,删除所有将在此处使用的外键映射。

您没有显示您的数据模型,但 participantsmessagessetting 应该都是双向的,其中反向关系称为 thread 然后一切都应该正常(我看不到任何其他明显的问题)。

顺便说一句,您应该使用路径模式来防止明显不正确的响应描述符一直被测试。