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

我遇到了一个问题。

在这个周末里,我一直在从一个web服务中抽取一个大XML的项目。

它基本上有3层 – 客户,经理,员工都是分层次的。 因此,第一次运行应用程序时,它会调用这个xml并parsing它,并在3个相关的实体 – 客户端,pipe理者和员工中创build所有条目。

每当应用程序启动,我需要拉同样的XML,但这次,我只需要“更新”任何已经改变的现有logging,或者为自上一次出现的新客户,经理或员工添加新的logging时间。

所以 – 正如我所说的那样,它正在全力以赴地parsing它,并创build正确的实体并填充所有的属性。

但是,在没有数据变化的情况下,在第二次启动时,它将DUPLICATING所有数据 – 而不是15个客户端(正确的数字),我有30个,等等。

我真的不得不在我的parsing中添加很多代码来检查,而不是创build一个新的NSManagedObject,我检查它是否已经在那里?

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

这是非常痛苦和长期的 – 是不是有一种方法可以使Core Data自动完成这些工作?

感谢您的任何帮助或build议。

正如在苹果文档中所述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]; 

就个人而言,我不喜欢这种方法,我写了这个代码片段,在一个有效的庄园处理这个代码,这是直接的! 我注意到苹果的方法,我遇到了不同的字符,如国会大厦的字母和空格string的问题。 下面的代码是testing和工作,如果你正确地重新命名所有相应的对象,我真的相信这是最有效的方式来完成不在核心数据中添加重复。

 -(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; } } 

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

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

在导入新行时,可以对现有行运行查询以查看是否已经存在。 要做到这一点,你创build一个NSFetchRequest对你的实体,设置谓词来查找guid属性,并设置最大行返回到1。

我build议在导入期间保留这个NSFetchRequest,以便在导入时可以重用它。 如果NSFetchRequest返回一行,则可以更新该行。 如果它不返回一行,那么你可以插入一个新的行。

如果正确完成,您会发现性能超过可接受的水平。

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