IOS Core Data Delete Parent Records With No Children

1k views Asked by At

I working on a "purge process" for my user-entered-data-centric app. Essentially there is a parent entity and a child entity. The system correctly deletes the child objects if I "swipe-delete" a parent object. So that part is working.

Now, what I will do is go through and delete all the child objects older then ?60? days that have been marked "reconciled". I should have no problem putting that fetch and delete request together. What I don't know is how do I go about fetching and deleting parent objects (older than ?60? days) who have no child objects?

I hope I don't have to iterate through the entire set, getting a count of child objects and saving that value to the parent then delete parents with "0" but I guess that will be my plan B. The data over a 60 day period could accrue 60-100 new parent objects and 150-300 new child objects and child objects should typically be marked as "reconciled" within 1-3 weeks of creation if the user stays on top of their personal job-related income items in a timely manner.

The parent entities are mostly string (about 20 attributes), but have 6 or so BOOL and decimal attributes as well, and the child are about 6 string, 2 decimal, and 1 BOOL attribute. So I'm not sure what that will translate to in terms of database size over say a year of typical usage if the user does not selectively delete anything.

I'm not seeing any need in an archiving process as this information is not "critical" over the long term. However, I can't expect my target audience to manually "swipe-delete" parent objects as a matter of habit when the time is right, meaning the data set will grow large over time if a purge process is not implemented.

Is there an abbreviated response to provide a general approach or method/sql syntax that Core Data will respond to? Or should I be approaching this problem from a different angle? Thanks in advance.

3

There are 3 answers

1
Anurag On

After you've deleted the child records, you can execute a query to retrieve the parent records with the given criteria and loop through each returned parent record and delete it. Here's how the fetch request would look like:

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"ParentEntity"];
request.predicate = [NSPredicate predicateWithFormat:@"date < %@ AND children.@count == 0", olderThan60Days];
request.includesPropertyValues = NO; // don't really care about these since it's for deletion

NSError *error;
NSArray *recordsToDelete = [context executeFetchRequest:request error:&error];

Execute the fetch request, and delete each returned object one by one.

0
Jovan Stankovic On

Swift 4, > iOS 9.0 with NSBatchDeleteRequest. Also wished there was a delete rule for this.

class func deleteParent(entity: String, withNoChildren children: String, inContext context: NSManagedObjectContext) throws {

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    let predicate = NSPredicate(format: "\(children).@count == 0")
    request.predicate = predicate

    let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)

    try context.execute(deleteRequest)
}
0
Chris Conover On

You may also be interested in this general solution for deleting parents with no children, since you are (or appear to be) deleting them at the same time:

iPhone Core Data: Cascading delete across a many-to-one relationship

This may be less explicit though.

I wish there was a delete rule for this case.