Приложение Песочница: закладка в области документов не разрешается; не возвращать ошибку - программирование
Подтвердить что ты не робот

Приложение Песочница: закладка в области документов не разрешается; не возвращать ошибку

Я подключаю свое приложение к песочнице и пытаюсь разрешить импорт/экспорт нескольких файлов, используя XML файл для ссылки на них. Чтобы мое приложение (или другое изолированное приложение) обращалось к файлам, перечисленным в XML, я также включаю в себя сериализованную закладку с областью безопасности. Я сериализую его, как описано в этом ответе, а мои юниверсы (которые не изолированы) записывают и читают данные XML без проблем. Когда мое приложение разрешает закладку, возвращает NSURL значение nil, как и ссылка 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], который не изменил (как и ожидалось, поскольку docURL уже находится в пределах после выбора в открытой панели

Кроме того, я указываю следующее в файле 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 вместо метода автореализованного класса тоже (на всякий случай)

  • Я вставил код разрешения URL сразу после создания закладки, и он отлично работает, создавая URL с областью безопасности

  • Я сделал po на первоначально созданной закладке (до сериализации), а затем по закладке после десериализации, и они соответствуют 100%. Сериализация не проблема

  • Я заменил вызов разрешения CFURLCreateByResolvingBookmarkData(..) без изменений. Если это ошибка, она присутствует в Core Foundation API, а также в слое Cocoa

  • Задание значения для bookmarkDataIsStale: не имеет эффекта

  • Если я укажу 0 для options:, то я do вернет действительный NSURL, но у него нет области безопасности, и поэтому последующие вызовы для чтения файла все еще остаются обязательно

    Другими словами, десериализованная закладка выглядит действительной. Если данные закладки были повреждены, я сомневаюсь, что NSURL сможет что-либо сделать с ней.

  • NSURL.h не содержал никаких полезных комментариев, чтобы указать на то, что я делаю неправильно

Кто-нибудь еще успешно использует закладки документов с защитой от безопасности в изолированном приложении? Если да, то чем вы занимаетесь иначе, чем я?

Запрос версии ОС

Может ли кто-нибудь, у кого есть доступ к блинчику Mountain Lion, проверить, показывает ли мой примерный проект ту же ошибку (отсутствие)? Если это ошибка, которая была исправлена ​​после Льва, я не буду беспокоиться об этом. Я еще не в программе разработчика, поэтому у меня нет доступа. Я не уверен, что ответ на этот вопрос нарушит NDA, но я надеюсь, что нет.

4b9b3361

Ответ 1

В коде Gist измените следующую строку в AppDelegate.m(строка 61):

[xmlTextFileData writeToURL:savePanel.URL atomically:YES];

к

[xmlTextFileData writeToURL:savePanel.URL atomically:NO];

Затем ваш код будет работать.

Причиной этого является, по всей вероятности, та же самая причина, по которой необходимо иметь существующий (но пустой) файл, который будет содержать закладки с областью документа, перед вызовом [anURL bookmarkDataWithOptions]: при создании экземпляра NSData ScopedBookmarkAgent добавляет что-то (например, тег, вероятно, расширенный атрибут файла) в этот файл.

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

Кстати: не нужно создавать закладки с приложениями, прежде чем передавать соответствующие URL-адреса в XML файл, содержащий закладки с областью документа.

Дополнение: com.apple.security.files.bookmarks.collection-scope переименована в com.apple.security.files.bookmarks.document-scope в 10.7.4.