2011-02-04 3 views
17

Я реализую процесс миграции вручную для приложения на основе 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 
+0

Покажите нам свой код. –

+0

Добавили код выше Jonathan - любой ввод оценили. – glenc

+0

Я столкнулся с той же проблемой. Я попытался помещать создающий файл, на который указывает newItemURL, в каталогах, соответствующих как «NSTemporaryDirectory()», так и «NSCachesDirectory», и он все равно выходит из строя без ошибок. Вам повезло? – Tony

ответ

1

я испытал проблемы со всей NSFileManager методы, используя URL-адрес на прошивке. Однако все методы, использующие Path, работают. Поэтому я думаю, что для этой цели вы должны использовать removeItemAtPath:error: и copyItemAtPath:toURL:error:.

Надеется, что это помогает

-1

В макинтоше файловой системы не чувствительна к регистру, но в IOS его. Даже если у вас нет двух файлов с одинаковым именем, но с разным случаем в одном месте, путь чувствителен к регистру. Так что если файл имеет .JPEG, а в вашем коде вы передаете ссылку с .jpeg, это не удастся. Это может быть не так, как с тобой, но только для того, чтобы поделиться

Хотя странно это должно дать вам ошибку.

Смежные вопросы