我有一个Generic方法,它根据JSON和实体中的键将JSON中的数据添加到Managed Object中。
我已经阅读了Apple的文档here,但是为了应用查找或创建模式,我似乎无法在获取之后浏览数据。
我不想使用三个嵌套循环来做到这一点,还有另外一种方法吗?
我应该循环jsonArrayData
还是entityMatchingNames
- (void) safeSetValuesForKeysWithDictionary:(NSArray *)jsonArrayData : (NSNumber *) entitySpecifier{
//Flag to determine entity name
NSString *entityName;
NSString *idName;
if([entitySpecifier isEqual:@1]){
entityName = @"Zones";
idName=@"zoneID";
}else if([entitySpecifier isEqual:@2]){
entityName = @"Categories";
idName=@"categoryID";
}else if ([entitySpecifier isEqual:@3]){
entityName = @"Companies";
idName=@"companyID";
}
//get entity
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.elRehabCoreData.managedObjectContext];
//get attributes of entity in core data
NSDictionary *entityAttributes = [entity attributesByName];
// Get the ids from json in sorted order.
NSMutableArray *entityIDs = [[NSMutableArray alloc]init];
for (NSDictionary *jsonValues in jsonArrayData) {
id value = [jsonValues objectForKey:idName];
[entityIDs addObject:value];
}
[entityIDs sortUsingSelector:@selector(compare:)];
// create the fetch request to get all Entities matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
NSString *filter = @"(%K IN %@)";
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: filter, idName, entityIDs]];
// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
@[ [[NSSortDescriptor alloc] initWithKey: idName ascending:YES] ]];
// Execute the fetch.
NSError *fetchError;
NSArray *entityMatchingNames = [self.elRehabCoreData.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
int i = 0;
for (NSDictionary *keyedValues in jasonArrayData) {
i++;
//Create NSManagedObject
NSManagedObject *managedObject = nil;
//insert
managedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.elRehabCoreData.managedObjectContext];
//loop over entities in core data
for (NSString *attribute in entityAttributes) {
id value = [keyedValues objectForKey:attribute];
if (value == nil) {
// Don't attempt to set nil, or you'll overwite values in self that aren't present in keyedValues
continue;
}
NSAttributeType attributeType = [[entityAttributes objectForKey:attribute] attributeType];
if ((attributeType == NSStringAttributeType) && ([value isKindOfClass:[NSNumber class]])) {
value = [value stringValue];
} else if (((attributeType == NSInteger16AttributeType) || (attributeType == NSInteger32AttributeType) || (attributeType == NSInteger64AttributeType) || (attributeType == NSBooleanAttributeType)) && ([value isKindOfClass:[NSString class]])) {
value = [NSNumber numberWithInteger:[value integerValue]];
} else if ((attributeType == NSFloatAttributeType) && ([value isKindOfClass:[NSString class]])) {
value = [NSNumber numberWithDouble:[value doubleValue]];
}
/*Add values for valid attributes */
//set value
[managedObject setValue:value forKey:attribute];
}
}
//save core data stack
[self.elRehabCoreData saveContext];
NSLog(@"%@ and #managed objects are: %i ", @"Saved and Finished ", i);
}
答案 0 :(得分:0)
我在http://www.raywenderlich.com/15916/how-to-synchronize-core-data-with-a-web-service-part-1教程中添加了一个if条件,用于检查JSONArray的计数是否与fetchedArray的计数相同,然后使用fetchedArray中的managedObject,否则插入一个新的ManagedObject。 只有当两个数组以完全相同的方式排序时,才可以使用此方法。
for (NSDictionary *keyedValues in sortedJSONArray) {
//Create NSManagedObject
NSManagedObject *managedObject = nil;
int updateInsert = 0;
//This is the part that determines whether to update or insert.
if(entityMatchingNames.count > i ){
managedObject = [entityMatchingNames objectAtIndex:i];
NSLog(@"In Managed Object %@, In JSON %@", [managedObject valueForKey:idName], [keyedValues valueForKey:idName] );
if ([[managedObject valueForKey:idName] isEqual:[NSNumber numberWithInteger:[[keyedValues valueForKey:idName] integerValue]]]) {
updateInsert = 1;
}
}else{
//insert
managedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.elRehabCoreData.managedObjectContext];
updateInsert = 1;
}
i++;
//loop over entities in core data
for (NSString *attribute in entityAttributes) {
id value = [keyedValues objectForKey:attribute];
if (value == nil) {
// Don't attempt to set nil, or you'll overwite values in self that aren't present in keyedValues
continue;
}
NSAttributeType attributeType = [[entityAttributes objectForKey:attribute] attributeType];
if ((attributeType == NSStringAttributeType) && ([value isKindOfClass:[NSNumber class]])) {
value = [value stringValue];
} else if (((attributeType == NSInteger16AttributeType) || (attributeType == NSInteger32AttributeType) || (attributeType == NSInteger64AttributeType) || (attributeType == NSBooleanAttributeType)) && ([value isKindOfClass:[NSString class]])) {
value = [NSNumber numberWithInteger:[value integerValue]];
} else if ((attributeType == NSFloatAttributeType) && ([value isKindOfClass:[NSString class]])) {
value = [NSNumber numberWithDouble:[value doubleValue]];
}
/*Add values for valid attributes */
//set value
if (updateInsert) {
[managedObject setValue:value forKey:attribute];
}
}
}