2
votes

I can't seem to find any reliable documentation that explains the correct procedure for deleting a UIManagedDocument, and in particular one where the iCloud options have been turned ON.

I understand that this option would delete the file at this fileURL. And this would appear to be fine if iCloud is not being used.

[[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];

If iCloud is being used then CoreData creates files all over the place, including in /Document/CoreDataUbiquitySupport and in the iCloud /CoreData folder. So in this case is it up to me to call removeUbiquitousContentAndPersistentStoreAtURL for each store in the UIManagedDocument prior to calling [NSFileManager removeItemAtURL]. If so is this documented somewhere ?

[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL
                                                                     options:@{NSPersistentStoreUbiquitousContentNameKey:fileName,
   NSMigratePersistentStoresAutomaticallyOption:@YES,
         NSInferMappingModelAutomaticallyOption:@YES,
                          NSSQLitePragmasOption:@{ @"journal_mode" : @"DELETE" }}
                                                                       error:&error];
2

2 Answers

1
votes

For iCloud core-data content you want to call the static method removeUbiquitousContentAndPersistentStoreAtURL:options:error: on the NSPersistentStoreCoordinator class, then call removeItemAtURL:error:

See deleteManagedDocumentWithIdentifier: in my APManagedDocument project. This is on the ubiquitous_experiment branch which I am currently working on finalizing before I merge it back down to the master branch.

2
votes

Here is my two cents on the issue. I tried what dtrotzjr recommended and didn't have a whole lot of success. It seems that removeUbiquitousContentAndPersistentStoreAtURL:options:error: is great for clearing out data in a UIManagedDocument, but the Logs folder is still there and so are the remnants of the file I'm trying to delete. Here is a simpler method for completely deleting a UIManagedDocument from iCloud or Local Docs:

+ (void)deleteDocumentURL:(NSURL *)url{
    //if we have an iCloud Document, remove it from the UbiquitouseKeyValueStore
    if ([self isiCloudURL:url]) {
        [[NSUbiquitousKeyValueStore defaultStore] removeObjectForKey:[url lastPathComponent]];
    }

    //do the delete on another thread
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
        NSError *coordinationError;

        [coordinator coordinateWritingItemAtURL:url
                                    options:NSFileCoordinatorWritingForDeleting
                                      error:&coordinationError
                                 byAccessor:^(NSURL *newURL) {
         NSError *removeError;
        //code for performing the delete
        [[NSFileManager defaultManager] removeItemAtURL:newURL error:&removeError];

        //if we have an iCloud file...
        if ([self isiCloudURL:url]) {
            //remove log files in CoreData directory in the cloud
            NSURL *changeLogsURL = [[self urlForiCloudLogFiles] URLByAppendingPathComponent:[url lastPathComponent]];
                [[NSFileManager defaultManager] removeItemAtURL:changeLogsURL error:&removeError];
            }
        }];
    });
}

This is pretty much the code from Stanford's CS193 course 2012 + the delete for the changeLogs folder and it works on local and iCloud docs. Please let me know if you see any issues with performing the delete this way.