Я использую метод NSFileManager replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
для перемещения файла sqlite в случае, если он не может быть перемещен с использованием метода replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
.Файл содержит три файла компонентов: один, заканчивающийся на .sqlite, другой, заканчивающийся на .sqlite-wal, и другой, заканчивающийся на .sqlite-shm.Все файлы правильно заменяют свои существующие аналоги методом replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
;однако только перемещенный файл .sqlite фактически удаляется из его исходного местоположения.Файлы .sqlite-wal и .sqlite-shm заменяются по желанию, но кажется, что они на самом деле копируются, а не перемещаются, поскольку эти два исходных файла все еще остаются на месте в конце их уважительной успешной операции replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
.Все происходит в одном и том же объеме, поэтому, похоже, нет причин, по которым можно было бы делать копии.Может кто-нибудь помочь мне понять, почему это может происходить?
Вот код.Сообщение о состоянии, когда оно регистрируется позже, гласит:
Успешно заменен файл SQLITE.Файл SQLITE НЕ все еще существует в исходном местоположении.Успешно заменен файл WAL.Файл WAL все еще существует в исходном местоположении.Успешно заменен файл SHM.Файл SHM все еще существует в исходном местоположении.
- (void)moveSqliteFileFromMigrateStorePathToFinalStorePathWithCompletionHandler:(void(^)(NSURL * migrateStoreURL,NSString * statusMessage,BOOL actuallyMovedFiles,BOOL movingHudIsRunning))handler {
__block NSString *statusMessage = nil;
__block BOOL actuallyMovedFiles = NO;
__block BOOL hudIsRunning = NO;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *applicationDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *migrateStorePath = [applicationDocumentsDirectory stringByAppendingPathComponent:@"MyAppData.sqlite"];
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [CoreDataController desiredFinalStoreURL];
NSString *finalStorePath = finalStoreURL.path;
NSString *fromWalPath = [migrateStorePath stringByAppendingString:@"-wal"];
NSString *fromShmPath = [migrateStorePath stringByAppendingString:@"-shm"];
BOOL walFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromWalPath];
BOOL shmFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromShmPath];
BOOL sqliteFileExists = [NSFileManager.defaultManager fileExistsAtPath:migrateStorePath];
if (sqliteFileExists || shmFileExists || walFileExists) {
[SVProgressHUD setForegroundColor:CPS_DARK_BLUE_COLOR];
[SVProgressHUD showWithStatus:NSLocalizedString(@"My App is updating. This one-time operation may take several minutes.",@"")];
hudIsRunning = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (sqliteFileExists) {
BOOL finalStorePathFileExists = [NSFileManager.defaultManager fileExistsAtPath:finalStorePath];
NSError * sqliteMoveError = nil;
BOOL successfulSqliteMove = NO;
BOOL replacingSqliteFile = NO;
if (finalStorePathFileExists) {
replacingSqliteFile = YES;
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [NSURL fileURLWithPath:finalStorePath];
successfulSqliteMove = [[NSFileManager defaultManager] replaceItemAtURL:finalStoreURL withItemAtURL:migrateStoreURL backupItemName:@"sqliteBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&sqliteMoveError];//NSFileManagerItemReplacementUsingNewMetadataOnly
}
else {
successfulSqliteMove = [[NSFileManager defaultManager] moveItemAtPath:migrateStorePath toPath:finalStorePath error:&sqliteMoveError];
}
if (sqliteMoveError) {
DLog(@"The error for the SQLITE move: %@",sqliteMoveError.localizedDescription);
}
if (successfulSqliteMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:migrateStorePath]) {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file DOES still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file DOES still exist in original location.", @"");
}
else {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file does NOT still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file does NOT still exist in original location.", @"");
}
}
else {
statusMessage = replacingSqliteFile?[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to replace SQLITE file", @""),sqliteMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to move SQLITE file", @""),sqliteMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SQLITE file to move.", @"");
}
if (walFileExists) {
NSString *toWalPath = [finalStorePath stringByAppendingString:@"-wal"];
BOOL toWalFileExists = [NSFileManager.defaultManager fileExistsAtPath:toWalPath];
NSError * walMoveError = nil;
BOOL successfulWalMove = NO;
BOOL replacingWalFile = NO;
if (toWalFileExists) {
replacingWalFile = YES;
NSURL *fromWalURL = [NSURL fileURLWithPath:fromWalPath];
NSURL *toWalURL = [NSURL fileURLWithPath:toWalPath];
//successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:fromWalURL withItemAtURL:toWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:toWalURL withItemAtURL:fromWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
}
else {
successfulWalMove = [[NSFileManager defaultManager] moveItemAtPath:fromWalPath toPath:toWalPath error:&walMoveError];
}
if (walMoveError) {
DLog(@"The error for the WAL move: %@",walMoveError.localizedDescription);
}
if (successfulWalMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace WAL file", @""),walMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move WAL file", @""),walMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No WAL file to move.", @"");
}
if (shmFileExists) {
NSString *toShmPath = [finalStorePath stringByAppendingString:@"-shm"];
BOOL toShmFileExists = [NSFileManager.defaultManager fileExistsAtPath:toShmPath];
NSError * shmMoveError = nil;
BOOL successfulShmMove = NO;
BOOL replacingShmFile = NO;
if (toShmFileExists) {
replacingShmFile = YES;
NSURL *fromShmURL = [NSURL fileURLWithPath:fromShmPath];
NSURL *toShmURL = [NSURL fileURLWithPath:toShmPath];
//successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:fromShmURL withItemAtURL:toShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:toShmURL withItemAtURL:fromShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
}
else {
successfulShmMove = [[NSFileManager defaultManager] moveItemAtPath:fromShmPath toPath:toShmPath error:&shmMoveError];
}
if (shmMoveError) {
DLog(@"The error for the SHM move: %@",shmMoveError.localizedDescription);
}
if (successfulShmMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace SHM file", @""),shmMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move SHM file", @""),shmMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SHM file to move.", @"");
}
if (handler) {
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
});
}
else {
if (handler) {
actuallyMovedFiles = NO;
hudIsRunning = NO;
statusMessage = NSLocalizedString(@"No SQLITE files to move.", @"");
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
}
}
РЕДАКТИРОВАТЬ: Благодаря @matt, проблема решена - для файлов shm и wal, 'to' и 'from' были смешанывверх.Я не могу поверить, что я пропустил это.Итак, теперь, как я и ожидал, из онлайн-исследований - даже если это не написано в документации - каждый файл фактически перемещается, а не копируется, когда метод замены успешен.С моим исправленным и исправленным кодом я получаю следующее сообщение:
Успешно заменен файл SQLITE.Файл SQLITE НЕ все еще существует в исходном местоположении.Успешно заменен файл WAL.WAL-файл НЕ все еще существует в исходном местоположении.Успешно заменен файл SHM.Файл SHM по-прежнему не существует в исходном местоположении.