iOSProgrammingIsFun iOSProgrammingIsFun - 3 months ago 10x
iOS Question

How to prevent Core Data making duplicates in iOS 5?

I've run into a problem.

Over the weekend I've been working on a project where I'm pulling a large xml from a webservice.

It basically has 3 tiers - Clients, Managers, Staff all hierarchical. So the first time the app runs, it pulls this xml and parses it and creates all the entries in the 3 releated Entities - Clients, Managers and Staff.

Every time the app launches I need to pull that same XML down, but this time, I only need to 'update' any of the existing records that have changed, or add new ones for new clients, managers or staff that have appeared since last time.

So - at the moment, as I said, it's pulling it all, parsing it correctly and creating the correct entities and filling in all the attributes.

However, with no data change, on the 2nd launch it's DUPLICATING all of the data - so instead of 15 clients ( the correct number ) I have 30 and so on...

Do I really have to add lots of code in my parsing to check that instead of creating a new NSManagedObject, I check if it's already there?

And if it is - I have to then manually check every attribute?

That's awfully painful and longwinded - isn't there a way to make Core Data do this kinda stuff for me - automatically?

Thanks for any help or suggestions.


As Stated in Apple Docs

You need to loop the data model and handle it from there like this


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

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

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];

Personally I do not like this method and I wrote this snippet of code that handles this in a pro-efficient manor and which is straight forward! I noticed with Apples method I ran into issues with strings having different characters such as capitol letters and spaces. Below code is tested and working if you rename all your corresponding objects correctly I honestly believe this is the most efficient way to accomplish not adding duplicates in core data.

    // Define our table/entity to use
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users"

    // 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"
    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