这是RestKit中的错误还是我没有正确配置它?当使用以下映射时,我得到了一个无限循环:
JSON:
[
{
"name": "Test 1",
"subtests": [
{
"name": "Subtest 1"
},
{
"name": "Subtest 2"
},
{
"name": "Subtest 3"
}
],
"children": ["Test 1"]
},
{
"name": "Test 2",
"subtests": [
{
"name": "Subtest 4"
},
{
"name": "Subtest 5"
},
{
"name": "Subtest 6"
}
],
"children": ["Test 2"]
}
]
地图提供商:
+ (RKMapping *)testMapping
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
mapping.identificationAttributes = @[ @"name" ];
[mapping addAttributeMappingsFromArray:@[ @"name" ]];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:[MappingProvider reflexiveTestMapping]]];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"subtests" toKeyPath:@"subtests" withMapping:[MappingProvider subTestMapping]]];
return mapping;
}
+ (RKMapping *)reflexiveTestMapping
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
mapping.identificationAttributes = @[ @"name" ];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"name" withMapping:[MappingProvider testMapping]]];
return mapping;
}
+ (RKMapping *)subTestMapping;
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([SubTest class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
mapping.identificationAttributes = @[ @"name" ];
[mapping addAttributeMappingsFromArray:@[ @"name" ]];
return mapping;
}
我在这里称之为:
- (IBAction)loadTestAndSubtestEntity:(id)sender {
RKLogConfigureByName("RestKit", RKLogLevelWarning);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
NSString *filePathComponent = [self.pathComponent stringByAppendingPathComponent:@"test.json"];
[[InfoDataModel sharedDataModel] importDataFromJsonFilePathComponent:filePathComponent withMapping:[MappingProvider testMapping]];
}
由于挂起,因此不会生成任何输出:self.storePath是用文件路径初始化的。
- (void)importDataFromJsonFilePathComponent:(NSString *)jsonFilePathComponent withMapping:(RKMapping *)mapping
{
if (self.storePath) {
NSString *jsonFilePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:jsonFilePathComponent];
MyLog(@"InfoDataModel. JSON file: %@", jsonFilePath);
RKManagedObjectImporter *importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:self.objectStore.managedObjectModel storePath:self.storePath];
importer.resetsStoreBeforeImporting = NO;
MyLog(@"InfoDataModel. Store: %@", self.storePath);
NSError *error = nil;
[importer importObjectsFromItemAtPath:jsonFilePath
withMapping:mapping
keyPath:nil
error:&error];
BOOL success = [importer finishImporting:&error];
if (success) {
[importer logSeedingInfo];
}
}
}
问题是有两个方法在相互调用。由于以下行,testMapping
方法调用reflexiveTestMapping
方法:
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:[MappingProvider reflexiveTestMapping]]];
并且reflexiveTestMapping
方法调用testMapping
方法是由于以下行:
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:@"name" withMapping:[MappingProvider testMapping]]];
这是一个硬循环,与映射没有直接关系,只是与您尝试创建映射的方式有关。
映射不需要以这种方式创建,因为JSON中的children
关系只包含名称,而不包含完整对象。
此递归的一个"解决方案"是限制基于在估计的跳跃上,在这种情况下是两次跳跃。
+ (RKMapping *)reflexiveTestMapping
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
mapping.identificationAttributes = @[ @"name" ];
// No more recursion calls from this point
return mapping;
}
这就是我修复递归的方法:
+ (RKMapping *)testMapping
{
RKEntityMapping *innerMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
innerMapping.identificationAttributes = @[ @"name" ];
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Test class]) inManagedObjectStore:[InfoDataModel sharedDataModel].objectStore];
mapping.identificationAttributes = @[ @"name" ];
[mapping addAttributeMappingsFromArray:@[ @"name" ]];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:innerMapping]];
return mapping;
}
这就是我对swift 所做的
class var keyAll: [String] {
return [
"title",
"desc"
]
}
class var objectMapping: RKObjectMapping {
let childMapping = RKObjectMapping(forClass: Category.self)
childMapping.addAttributeMappingsFromArray(keyAll)
let mapping = RKObjectMapping(forClass: Category.self)
mapping.addAttributeMappingsFromArray(keyAll)
mapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: keyChilds, toKeyPath: keyChilds, withMapping: childMapping))
return mapping
}