Reputation: 691
What I have is a Core Data Entity called "MyDocument" which has these properties
I download a bunch of files from the server, save them on the disk in the "Caches" Folder and then Insert rows in the DB for each document. This just makes it easier to manage documents in the app without listing directory contents etc...
Everything seems OK, except that when I delete the Entity, I also want to delete the associated file on disk. I could easily do something like this
for(MyDocument *myDocument in ParentEntity.mydocuments)
{
[[NSFileManager defaultManager] removeItemAtURL:[NSURL fileURLWithPath:myDocument.fileURL] error:nil];
[context deleteObject:myDocument];
}
But I am trying to get this done via accessors....so that I can call - deleteObject:myDocument
from anywhere and be sure that the associated file would also get deleted.
I know I could use Core Data's External File Storage option and not worry about this at all but I am using QLPreviewController to preview these documents, and QLPreviewController needs a file URL to be able to preview the item. And if I save the documents in Core Data, I would have to write the file to disk from the stored NSData every time Preview needs it. It did not make sense so I decided to store them externally myself and keep a reference in DB.
So, how would I write a custom accessor that would jump in just before object is about to be deleted and delete the associated file and then carry on with deleting the actual Entity..
Thanks in advance
Upvotes: 1
Views: 188
Reputation: 5558
NSManagedObject -prepareForDeletion is most certainly what you need to implement in your entity, to take care of associated resources.
Core Data calls prepareForDeletion for every deleted entity while still alive and well and before the delete rules propagation. This is the right place to implement anything more complex than the very basic rules Core Data provides.
It works without adding stuff to the NSManagedObjectContext, it will work with the default NSManagedObjectContext -deleteObject, and it will not mess with the NSUndoManager. Of course, you have to use custom classes for your entities.
Upvotes: 2
Reputation: 80265
I think the cleanest way is to simply add a custom method to your NSManagedObject
subclass. Below I made this a category of NSManagedObjectContext
, but you could also do it just as a MyDocument
instance method. In this way you can explicitly delete the Entity and associated document while still having the option to just delete the entity. Also, you would avoid deleting things accidentally in the future when you not that familiar with your code any more ;-).
@interface NSManagedObjectContext (customDelete)
-(void)deleteMyDocumentObjectAndAssociatedFiles:(MyDocument *)object;
@end
@implementation NSManagedObjectContext (customDelete)
-(void)deleteMyDocumentObjectAndAssociatedFiles:(MyDocument *)object {
[[NSFileManager defaultManager] removeItemAtURL:
[NSURL fileURLWithPath:object.fileURL] error:nil];
[self deleteObject:object];
}
@end
Or as MyDocument
method (don't know if this "self deletion" works):
-(void)deleteSelfAndAssociatedFiles {
[[NSFileManager defaultManager] removeItemAtURL:
[NSURL fileURLWithPath:self.fileURL] error:nil];
[self.managedObjectContext deleteObject:self];
}
Upvotes: 1