Сохранение на месте в песочнице OS X - PullRequest
2 голосов
/ 26 ноября 2011

Я разрабатываю изолированное приложение для Mac OS X 10.7 и пытаюсь реализовать сохранение файла способом, аналогичным NSDocument:

  1. Переписать новое содержимое файла во временноеfile
  2. Перезаписать исходный файл временным файлом

У меня проблема в том, что песочница запрещает шаг 2. Я вижу в консоли следующую строку:

sandboxd: XXXX deny file-write-create /Volumes/Home/sbooth/Test Files/Test

У меня уже есть этот файл, открытый для чтения и записи, и у меня включено разрешение на чтение и запись для файловой системы.Я знаю, что NSDocument делает это без специальных прав, поэтому я пытаюсь выяснить, что я пропустил.

Вот как я сейчас делаю (эта часть приложения на C ++, а не Objective-C / C ++):

FSRef tempFileFSRef;
if(noErr != FSPathMakeRef((const UInt8 *)tempFileName, &tempFileFSRef, NULL))
  ; // Handle it
CFURLRef destinationDirURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, mURL);
FSRef destinationDirFSRef;
if(!CFURLGetFSRef(destinationDirURL, &destinationDirFSRef))
  ; // Handle it
CFRelease(destinationDirURL), destinationDirURL = NULL;
CFStringRef destinationName = CFURLCopyLastPathComponent(mURL);
FSRef target;
OSStatus result = FSCopyObjectSync(&tempFileFSRef, &destinationDirFSRef, destinationName, &target, kFSFileOperationOverwrite | kFSFileOperationSkipSourcePermissionErrors);
if(noErr != result)
  ; // Handle it

Код работает правильно, если я отключаю песочницу.

Редактировать: Femi запросила дополнительную информацию.Я открываю файл с помощью C stdio:

FILE *f = fopen(reinterpret_cast<const char *>(buf), "r");

и он закрывается с помощью fclose до создания временного файла.

Мои права:

<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.assets.music.read-write</key>
    <true/>
    <key>com.apple.security.files.downloads.read-write</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
</dict>

Стоит также отметить, что Apple в своем Руководстве по разработке изолированной программной среды приложения говорит, что:

Если вы управляете документами с использованием любой технологии, отличной от класса NSDocument, вы должны перейти на использование этойучебный класс.Класс NSDocument автоматически работает с Powerbox.NSDocument также поддерживает хранение документов в вашей песочнице, если пользователь перемещает их с помощью Finder.

1 Ответ

0 голосов
/ 14 января 2012

Песочница позволяет только читать и писать из контейнера вашего приложения.Если у вас включено право на чтение / запись, то у вас есть доступ только к файлам, которые открыты через OpenSavePanel (или к какому-либо методу, например перетаскиванию значка в док-станцию, где пользователь специально открыл файл).Это сильно ограничит работу приложения с файлами в файловой системе.

Таким образом, если у вашего приложения есть разрешение на запись поверх рассматриваемого документа, вы можете записать свой временный файл в контейнер приложений, а затемполучить содержимое временного файла, а затем сохранить в исходное местоположение.Однако это предполагает, что ваше приложение поддерживает разрешения для исходного файла на протяжении всего процесса.

Итак, я предлагаю убедиться, что все ваши записи выполняются в контейнере приложения, а затем убедиться, что у вашего приложения все еще есть разрешение.записать в реальное местоположение файла перед вызовом функции сохранения.

Недавно я написал аналогичный вопрос, в котором мое приложение потеряло доступ к файлам, которые были открыты из-за того, что другое (не изолированное от песочницы) приложение сохранило в тот же файл.Песочница предоставила этому приложению доступ к моему документу и удалила разрешения из приложения.

...