Я помещаю свое приложение в песочницу и пытаюсь разрешить импорт/экспорт нескольких файлов, используя файл XML для ссылки на них. Чтобы разрешить моему приложению (или другому изолированному приложению) доступ к файлам, перечисленным в XML, я также включаю сериализованную закладку с областью безопасности. Я сериализую его, как описано в этом ответе, и мои модульные тесты (которые не в песочнице) записывать и читать XML-данные без проблем. Когда мое приложение разрешает закладку, возвращаемое NSURL
равно нулю, как и ссылка NSError
. Поскольку я не верю, что это должно быть так, почему это происходит? Я могу обойти это, предложив пользователю выбрать файл/каталог с NSOpenPanel
, но я все же хотел бы, чтобы закладки работали должным образом.
Воспроизведено в тестовом проекте
Чтобы воспроизвести дома, создайте новое приложение Cocoa в Xcode и используйте следующий Gist для файлов в проекте: https://gist.github.com/2582589 (обновлен правильным циклом следующего просмотра)
Затем следуйте инструкции Apple по кодовой подписи проекта. Вы воспроизводите проблему (которую я отправил в Apple как rdar://11369377) с помощью последовательно нажимая кнопки. Вы выбираете любой файл на диске (вне контейнера приложения), затем XML для экспорта, а затем тот же XML для импорта.
Надеюсь, вы, ребята, сможете помочь мне понять, что я делаю неправильно. Либо я делаю что-то не так, и фреймворк ошибочно держится сам за себя, либо я делаю это правильно, а он полностью сломан. Я стараюсь не винить фреймворк, так что же это? Или есть другая возможность?
Пример кода
Экспорт XML в docURL
:
// After the user picks an XML (docURL) destination with NSSavePanel
[targetURL startAccessingSecurityScopedResource];
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:docURL
error:&error];
[targetURL stopAccessingSecurityScopedResource];
Импорт XML из docURL
:
// After the user selected the XML (docURL) from an NSOpenPanel
NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:docURL
bookmarkDataIsStale:nil
error:&error];
Я попытался окружить этот вызов с помощью [docURL ..AccessingSecurityScopedResource]
, что не имело значения (как и ожидалось, поскольку URL-адрес документа уже находится в пределах области действия после выбора на открытой панели
Кроме того, я указываю следующее в моем файле app.entitlements
:
com.apple.security.files.user-selected.read-write
com.apple.security.files.bookmarks.app-scope
com.apple.security.files.bookmarks.collection-scope
Как упоминалось выше, второй шаг (разрешение закладки) завершается, но оставляет как error
, так и result
nil. Поскольку я внедрял песочницу, большинство ошибок, которые я сделал, привели к возвращению NSError
, что помогло мне устранить ошибку. Но теперь ошибки нет, и URL-адрес не разрешается.
Различные действия по устранению неполадок
Я попытался поместить файл XML в песочницу своего приложения, но это не имело значения, поэтому доступ к файлу XML не является проблемой.
Приложение использует ARC, как и модульные тесты, которые проходят успешно. Я также пытался использовать alloc/init вместо метода класса autoreleased (на всякий случай)
Я вставил код разрешения URL-адреса сразу после создания закладки, и он работает нормально, создавая URL-адрес с областью безопасности.
Я сделал
po
на изначально созданной закладке (до сериализации), а затем на закладке после десериализации, и они совпадают на 100%. Сериализация не проблемаЯ заменил вызов разрешения на
CFURLCreateByResolvingBookmarkData(..)
без изменений. Если это ошибка, она присутствует в Core Foundation API, а также в слое Cocoa.Указание значения для
bookmarkDataIsStale:
не влияетЕсли я укажу
0
дляoptions:
, то я делаю возвращаю действительный NSURL, но он не имеет области безопасности, и поэтому последующие вызовы для чтения файла все еще терпят неудачу.Другими словами, десериализованная закладка кажется действительной. Если бы данные закладок были повреждены, я сомневаюсь, что NSURL сможет что-то с ними сделать.
NSURL.h
не содержит полезных комментариев, чтобы указать на то, что я делаю неправильно
Кто-нибудь еще успешно использует закладки документов с областью безопасности в изолированном приложении? Если да, то что вы делаете иначе, чем я?
Запрос версии ОС
Может ли кто-нибудь, имеющий доступ к бета-версии Mountain Lion, проверить, показывает ли мой пример проекта ту же ошибку (отсутствие)? Если это ошибка, которая была исправлена после Lion, я не буду об этом беспокоиться. Я еще не в программе для разработчиков, поэтому у меня нет доступа. Я не уверен, что ответ на этот вопрос нарушит NDA, но надеюсь, что нет.
writeToURL:atomically:
перемещает файл. Конечно, когда я иду читать закладку, я должен получитьNSError
обратно. Было бы легче отслеживать происходящее. - person Dov   schedule 10.07.2012