如何防止核心数据在iOS 5中重复?

iOS*_*Fun 9 web-services core-data duplicates ios

我遇到了一个问题.

在周末,我一直在研究一个项目,我正在从Web服务中提取大型xml.

它基本上有3层 - 客户,经理,员工都是等级的.因此,第一次运行应用程序时,它会提取此xml并对其进行解析,并在3个相关实体 - 客户端,经理和员工中创建所有条目.

每次应用程序启动时,我都需要将相同的XML拉下来,但这一次,我只需要"更新"任何已更改的现有记录,或者为自上次出现以来出现的新客户,经理或员工添加新记录时间.

所以 - 就在我说的那一刻,它正在全力以赴,正确解析并创建正确的实体并填充所有属性.

但是,如果没有数据更改,在第二次启动时它会重复所有数据 - 所以不是15个客户端(正确的数字)我有30个等等......

我是否真的必须在我的解析中添加大量代码来检查而不是创建一个新的NSManagedObject,我检查它是否已经存在?

如果是 - 我必须手动检查每个属性?

那是非常痛苦和长篇大论 - 是不是有办法让Core Data为我做这种事 - 自动?

感谢您的任何帮助或建议.

dom*_*dom 12

我担心你必须自己保持你的数据库清理...最简单的方法是使用NSFetchRequest:导入更新的数据时,你可以对现有数据运行查询并决定你想做什么.

正如Marcus S. Zarra在另一个关于这个主题的帖子中提到的:

导入新行时,可以对现有行运行查询,以查看它是否已存在.为此,您需要针对您的实体创建NSFetchRequest,将谓词设置为查找guid属性并将返回的最大行设置为1.

我建议您在导入期间保留此NSFetchRequest,以便在进行导入时可以重复使用它.如果NSFetchRequest返回一行,您可以更新该行.如果它没有返回一行,那么您可以插入一个新行.

如果操作正确,您会发现性能超出可接受范围.

另一个获得良好信息的来源是"苹果编程指南:核心数据编程指南"


Fre*_*pl3 3

如 Apple 文档中所述https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html

您需要循环数据模型并从那里处理它,如下所示

例子:

// loop over employeeIDs
// anID = ... each employeeID in turn
// within body of loop

NSString *predicateString = [NSString stringWithFormat: @"employeeID == %@", anID];

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
Run Code Online (Sandbox Code Playgroud)

就我个人而言,我不喜欢这种方法,我编写了这段代码,以高效的方式处理这个问题,而且很直接!我注意到,使用苹果的方法时,我遇到了具有不同字符(例如大写字母和空格)的字符串的问题。如果您正确重命名所有相应的对象,下面的代码经过测试并且可以工作,我真诚地相信这是实现不在核心数据中添加重复项的最有效方法。

-(void)AvoidDuplicatesinDataModel
{
    // Define our table/entity to use
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users"
                                              inManagedObjectContext:managedObjectContext];

    // Setup the fetch request
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];

    // Define how we will sort the records
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"users"
                                                                   ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    [request setSortDescriptors:sortDescriptors];
    [sortDescriptor release];

    // Fetch the records and handle an error
    NSError *Fetcherror;
    NSMutableArray *mutableFetchResults = [[managedObjectContext
                                            executeFetchRequest:request error:&Fetcherror] mutableCopy];

    if (!mutableFetchResults) {
        // Handle the error.
        // This is a serious error
    }

    //here usersNameTextField.text can be any (id) string that you are searching for
    if ([[mutableFetchResults valueForKey:@"users"]
         containsObject:usernameTextField.text]) {
        //Alert user or handle your duplicate methods from here
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)