Я реализую процесс миграции вручную для приложения на основе CoreData, и после того, как миграция завершена успешно, я пытаюсь переместить перенесенный DB обратно на верхняя часть оригинала с использованием replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
.replaceItemAtURL не работает без ошибок в iOS, но отлично работает на OSX
Проблема в том, что в iOS ничего не будет сделано, чтобы этот метод вернул ДА, однако он также никогда не помещает ничего в указатель ошибки, чтобы вы могли видеть, что происходит не так.
Я читал вещи в другом месте (например, http://www.cocoabuilder.com/archive/cocoa/287790-nsdoc-magic-file-watcher-ruins-core-data-migration.html), что указывает на то, что не было бы прекращения всех объектов CoreData (например, NSMigrationManager, NSManagedObjectModel и т. Д.), Прежде чем пытаться заменить это может быть причиной, но это не так. Я даже реализовал немного двух файлов для создания и замены файлов, которые вообще не включали базы данных CoreData, чтобы убедиться, что материал CoreData не имеет к этому никакого отношения.
Затем я заметил в official documentation, что newitemURL
должен находиться в каталоге, который считается подходящим для временных файлов. Я предположил, что это означает, что каталог был возвращен URLForDirectory:inDomain:appropriateForURL:create:error:
, используя NSItemReplacementDirectory
в качестве пути поиска.
Это тоже не сработало! Я закончил тем, что вернулся к реализации логики замены, используя отдельные операции, но это не атомно и небезопасно, и все эти плохие вещи.
У кого-нибудь есть рабочий фрагмент кода, который работает на iOS, который возвращает ДА от вызова до replaceItemAtURL
или фактически помещает информацию об ошибке в указатель ошибки?
Любая помощь очень ценится.
EDIT - Тестовый код приведен ниже. Это работает в application:didFinishLaunchingWithOptions:
в основной теме.
NSFileManager *fm = [[NSFileManager alloc] init];
NSError *err = nil;
NSURL *docDir = [NSURL fileURLWithPath:[self applicationDocumentsDirectory]];
NSURL *tmpDir = [fm URLForDirectory:NSItemReplacementDirectory
inDomain:NSUserDomainMask
appropriateForURL:docDir
create:NO
error:&err];
NSURL *u1 = [docDir URLByAppendingPathComponent:@"f1"];
NSURL *u2 = [tmpDir URLByAppendingPathComponent:@"f2"];
NSURL *repl = nil;
[fm createFileAtPath:[u1 path]
contents:[[NSString stringWithString:@"Hello"]
dataUsingEncoding:NSUTF8StringEncoding]
attributes:nil];
[fm createFileAtPath:[u2 path]
contents:[[NSString stringWithString:@"World"]
dataUsingEncoding:NSUTF8StringEncoding]
attributes:nil];
BOOL test = [fm replaceItemAtURL:u1 withItemAtURL:u2 backupItemName:@"f1backup"
options:0 resultingItemURL:&repl error:&err];
// At this point GDB shows test to be NO but error is still nil
Покажите нам свой код. –
Добавили код выше Jonathan - любой ввод оценили. – glenc
Я столкнулся с той же проблемой. Я попытался помещать создающий файл, на который указывает newItemURL, в каталогах, соответствующих как «NSTemporaryDirectory()», так и «NSCachesDirectory», и он все равно выходит из строя без ошибок. Вам повезло? – Tony