What is the best way to remove logs file Core Data

2020-05-02 01:22发布

问题:

I would have thought NSFileManagers method of removeItemAtURL:error: would remove the Core Data log files created when using UIManagedDocuments with iCloud.

What is the best way to make sure all of these log files are removed?

回答1:

I have used...

- (void)deleteRemnantsOfOldDatabaseDocumentAndItsTransactionLogsWithCompletionHandler:(completion_success_t)completionBlock
{    
    __weak CloudController *weakSelf = self;

    NSURL *databaseStoreFolder = self.iCloudDatabaseStoreFolderURL;
    NSURL *transactionLogFolder = self.transactionLogFilesFolderURL;

    [self deleteFileAtURL:databaseStoreFolder withCompletionBlock:^(BOOL docSuccess) {
        [weakSelf deleteFileAtURL:transactionLogFolder withCompletionBlock:^(BOOL logSuccess) {
            completionBlock(docSuccess && logSuccess);
        }];
    }];
}

In conjunction with...

- (void)deleteFileAtURL:(NSURL *)fileURL withCompletionBlock:(completion_success_t)completionBlock
{    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
        NSError *coordinatorError = nil;
        __block BOOL success = NO;

        [fileCoordinator coordinateWritingItemAtURL:fileURL
                                            options:NSFileCoordinatorWritingForDeleting
                                              error:&coordinatorError
                                         byAccessor:^(NSURL *writingURL) {

                                             NSFileManager *fileManager = [[NSFileManager alloc] init];
                                             NSError *removalError = nil;
                                             if ([fileManager fileExistsAtPath:[writingURL path]]) {
                                                 if (![fileManager removeItemAtURL:writingURL error:&removalError]) {
                                                     NSLog(@"deleteFileAtURL: removal error: %@", removalError);
                                                 } else {
                                                     success = YES;
                                                 }
                                             } 
                                         }];

        if (coordinatorError) {
            NSLog(@"deleteFileAtURL: coordinator error: %@", coordinatorError);
        }

        completionBlock(success);
    });
}

Note: this was used for a single document toolbox style app, and was intended more for clearing out the iCloud container before creating a brand new document, in an 'apparently' empty iCloud store for the first time. But I'm sure it can be adapted without too much work.

Oops, the above won't make sense/work without:

typedef void (^completion_success_t)(BOOL success);

You can debug the contents of your iCloud container and verify things have been removed by using a method like (which to be honest I've probably lifted from somewhere else and modified):

- (void)logDirectoryHierarchyContentsForURL:(NSURL *)url
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtURL:url
                                                   includingPropertiesForKeys:@[NSURLNameKey, NSURLContentModificationDateKey]
                                                                      options:NSDirectoryEnumerationSkipsHiddenFiles
                                                                 errorHandler:nil];

    NSMutableArray *results = [NSMutableArray array];

    for (NSURL *itemURL in directoryEnumerator) {
        NSString *fileName;
        [itemURL getResourceValue:&fileName forKey:NSURLNameKey error:NULL];

        NSDate *modificationDate;
        [itemURL getResourceValue:&modificationDate forKey:NSURLContentModificationDateKey error:NULL];

        [results addObject:[NSString stringWithFormat:@"%@ (%@)", itemURL, modificationDate]];
    }

    NSLog(@"Directory contents: %@", results);
}

And it's also worth logging onto developer.icloud.com and examining what is actually in the iCloud store. There is sometimes a difference between what is retained in the device ubiquity container, and what is actually in the iCloud server folder structure. Between all of these you can get quite a good idea of what's going on.