Подтвердить что ты не робот

ReplaceItemAtURL выходит из строя без ошибок в iOS, но отлично работает на OSX

Я реализую процесс миграции, инициируемый вручную для приложения на основе CoreData, и после того, как миграция завершена успешно, я пытаюсь переместить перенесенный DB обратно поверх исходного с помощью replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:.

Проблема в том, что в iOS я ничего не сделаю, если этот метод вернет YES, однако он также никогда не помещает в указатель ошибки ничего, чтобы вы могли видеть, что происходит не так.

Я читал бы что-то в другом месте (например, http://www.cocoabuilder.com/archive/cocoa/287790-nsdoc-magic-file-watcher-ruins-core-data-migration.html), указывающий, что не отключать все объекты CoreData (например, NSMigrationManager, NSManagedObjectModel и т.д.), прежде чем пытаться заменить может быть причиной, но это не так. Я даже реализовал немного двух файлов для создания и замены файлов, которые вообще не включали базы данных CoreData, чтобы убедиться, что материал CoreData не имеет к этому никакого отношения.

Затем я заметил в официальной документации , что newitemURL должен находиться в каталоге, который считается подходящим для временных файлов. Я предположил, что это означает, что каталог, возвращаемый URLForDirectory:inDomain:appropriateForURL:create:error:, используя NSItemReplacementDirectory в качестве пути поиска.

Это тоже не сработало! Я закончил тем, что вернулся к реализации логики замены, используя отдельные операции, но это не атомно и небезопасно, и все эти плохие вещи.

Есть ли у кого-нибудь рабочий фрагмент кода, который работает на iOS, который возвращает YES из вызова 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
4b9b3361

Ответ 1

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

Надеюсь, что это поможет

Ответ 2

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

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