syedfa
syedfa

Reputation: 2809

Unable to replace one Entity with another in Core Data in iOS

I am working on an iOS application where I am using Core Data for storage. In my store, every entity will be unique, and I'm building a function where I replace one existing entity with another that I pass in. Here is an example of an entity that I pass:

    NSManagedObjectContext *context = [[MyDB sharedInstance] managedObjectContext];

    User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:context];

    NSNumber *userNumber = 12345;

    user.id = userNumber;
    user.name = @"John Doe";
    user.email = @"[email protected]";
    user.createdDate = [NSDate date];

    [[MyDB sharedInstance] updateUser:user];

Inside my Core Data storage, I have an identical Entity already, except that the email address is "[email protected]". My update at the moment looks like this:

-(void)updateUser:(User *)user {

    NSError *error;
    NSManagedObjectContext *context = [[MyDB sharedInstance] managedObjectContext];

    // Create fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    // Create predicate
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"id == %@", user.id];
    [fetchRequest setPredicate:pred];

    NSArray *results = [context executeFetchRequest:fetchRequest error:&error];

    if (error) {
        // handle fetch error
    } else {

        user = [[User alloc] initWithEntity:entity insertIntoManagedObjectContext:context];

        for (User *recordToDelete in results) {

            [context deleteObject:recordToDelete];//record gets deleted here, which is fine

        }

        [context save:&error]; //this doesn't save the new entity that I passed in

        if (error) {
            // handle save error
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }

    }


    [fetchRequest setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id=%@", 12345];
    [fetchRequest setPredicate:pred];

    NSArray *items = [context executeFetchRequest:fetchRequest error:&error];

    for (User *testObject in items) {

        NSLog(@"ID: %@, Name: %@, Email: %@, Created Date: %@", [testObject id], [testObject name], [testObject email], [testObject createdDate]);

    }

}

The problem is that the above function deletes the existing record in the store, however, it fails to add the new entity that replaces it. How can I correct this?

Upvotes: 0

Views: 771

Answers (2)

Petro Korienev
Petro Korienev

Reputation: 4027

Also, i think you don't clearly understand what is NSManagedObjectContext. It's something like in-memory object cache. So, if you create object in context, it is tied to context. Object has reference to context, so passing context with object is not necessary - object's context can be obtained from it. Also, contexts and objects are not thread-safe - you cannot pass managed objects between threads and use same context in different threads. Instead, you have to:
1) Create context for every thread
2) If you need to pass something between threads, pass object.objectId from one thread, and in another thread do [context objectWithID:]. It's extremly fast, efficient and safe.

Upvotes: 2

Adnan Aftab
Adnan Aftab

Reputation: 14477

You are not calling save method on managed object context. Call save method on managedObjectContext in which you are creating new object. [managedObjectContext save:nil];

Recmonded way is. First fetch object depending on number, and delete it. After that create managed object. At the end call Save on context.

Upvotes: 1

Related Questions