Ios 使用核心数据在泛型方法中查找或创建模式

Ios 使用核心数据在泛型方法中查找或创建模式,ios,core-data,insert-update,Ios,Core Data,Insert Update,我有一个通用方法,它基于JSON和实体中的键将JSON中的数据添加到托管对象中。 我已经阅读了苹果公司的文档,但不知何故,我似乎无法在获取数据后遍历数据,以便应用查找或创建模式。 我不想使用三个嵌套循环来实现这一点,还有其他方法吗? 我应该循环使用jsonArrayData还是entityMatchingNames - (void) safeSetValuesForKeysWithDictionary:(NSArray *)jsonArrayData : (NSNumber *) entityS

我有一个通用方法,它基于JSON和实体中的键将JSON中的数据添加到托管对象中。 我已经阅读了苹果公司的文档,但不知何故,我似乎无法在获取数据后遍历数据,以便应用查找或创建模式。 我不想使用三个嵌套循环来实现这一点,还有其他方法吗? 我应该循环使用
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);



}

我在教程中添加了一个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];
        }




    }

}