NSBatchDeleteRequest does not delete external files

When using batch delete to delete a core data object, the object's external binary data is not deleted. Am I doing something wrong? Or is this a bug on Apple's end?


To reproduce:

-------------


I've set up a simple Core Data project. The data model defines an `ImageProperty` entity with a binary data attribute that "Allows External Storage".


I don't make any changes to the implementation of the persistentContainer that is provided by Apple:


lazy var persistentContainer: NSPersistentContainer = {
     let container = NSPersistentContainer(name: "ExternalStorage")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        ...
    })
    return container
}()


On application launch, I create and save an instance of `ImageProperty` with data large enough to be stored externally. I then immediately delete that property using a batch delete:


let entityName = String(describing: ImageProperty.self)

// Create property

let entity = NSEntityDescription.entity(forEntityName: entityName, in: persistentContainer.viewContext)!
let property = ImageProperty(entity: entity, insertInto: persistentContainer.viewContext)
property.data = NSData(contentsOfFile: Bundle.main.path(forResource: "sample-house-a", ofType: "jpg")!)
try! persistentContainer.viewContext.save()

// Batch-delete property

let fetch: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
let request = NSBatchDeleteRequest(fetchRequest: fetch)
_ = try! self.persistentContainer.viewContext.execute(request) as! NSBatchDeleteResult
try! self.persistentContainer.viewContext.save()


When I check the app's sandbox, the item has been deleted from the database, but the external file still exists. Why?

Replies

I'm having this same problem. This behavior is very counterintuitive and can lead to filling up the disk. How can we ensure that externally stored data is deleted along with the record?