What is the best way to remove logs file Core Data creates, when removing a UIManagedDocument from iCloud?

后端 未结 1 1829
忘了有多久
忘了有多久 2021-01-26 05:06

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

1条回答
  •  迷失自我
    2021-01-26 05:52

    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.

    0 讨论(0)
提交回复
热议问题