2012-04-21 3 views
16

Я песочница моего приложения и пытаюсь разрешить импорт/экспорт нескольких файлов, используя XML-файл, чтобы ссылаться на них. Чтобы мое приложение (или другое изолированное приложение) обращалось к файлам, перечисленным в XML, я также включаю в себя сериализованную закладку с областью безопасности. Я сериализую его, как описано в this answer, и мои модульные тесты (которые не песочницы) записывают и читают данные XML без проблем. Когда мое приложение разрешает закладку, возвращается NSURL, равно нулю, как и ссылка NSError. Поскольку я не верю, что так должно быть, почему это происходит? Я могу обойти это, предложив пользователю выбрать файл/каталог с NSOpenPanel, но мне все равно хотелось бы, чтобы закладки работали так, как должны.Приложение Песочница: закладка в области документов не разрешается; не возвращая никакую ошибку

Воспроизводится в тестовом проекте

Чтобы воспроизвести в домашних условиях, создать новое приложение какао в Xcode, и использовать следующие GIST для файлов в проекте: https://gist.github.com/2582589 (обновляются с соответствующим следующим зрением петля)

Затем следуйте Apple's instructions, чтобы код подписал проект. Вы воспроизводите проблему (которую я отправил в Apple как rdar://11369377), щелкнув последовательно кнопки. Вы выбираете любой файл на диске (вне контейнера приложения), затем экспортируете XML, а затем тот же XML для импорта.

Надеюсь, вы, ребята, сможете мне помочь выяснить, что я делаю неправильно. Либо я делаю что-то неправильно, и фреймворк ошибочно придерживается самого себя, или я делаю это правильно, и он полностью сломан. Я стараюсь не blame the framework, так что это? Или есть еще одна возможность?

Пример кода

Экспорт 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 ноль. Поскольку я выполнял песочницу, большинство ошибок, которые я сделал, привели к возврату NSError, что помогло мне решить проблему. Но теперь нет ошибки, и URL не разрешен.

Разные действий по устранению неполадок

  • Я попытался поместить XML-файл в песочницу моего приложения, которое не делают разницы, так что доступ к файлу XML не проблема

  • Приложение использует ARC, но так же и модульные тесты, которые преуспевают. Я попытался с помощью Alloc/Init вместо метода autoreleased класса тоже (на всякий случай)

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

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

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

  • Выбор значения для bookmarkDataIsStale: не имеет никакого эффекта

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

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

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

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

OS Version Запрос

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

+0

В любом случае я ничего не мог поделать, но этот вопрос - это немного журнал путешествий в вашем исследовании. Было бы здорово, если бы вы могли переделать его, забыв о том, КАК вы получили, где вы это сделали. Не оскорбление: вопрос кажется качественным, что отражается на 5 upvotes (теперь 6 с моим). –

+0

@Yar спасибо за вход и верхний знак. Я сохранил (большинство) обновления по двум причинам. Прежде всего, я документирую шаги, которые я пробовал, чтобы другие могли избежать повторного устранения неполадок, а во-вторых, я разместил обновления внизу (вместо того, чтобы обрабатывать новую информацию в основном вопросе), чтобы сделать более понятными для тех, кто задал вопрос, что фактически изменился. Я планировал изменить вопрос после ответа. Вы предлагаете переупорядочить содержание в вопросе или удалить менее важные части? – Dov

+0

обе. Это увеличит вашу вероятность получить ответ, а также сделает сообщение более актуальным для будущих пользователей, у которых есть совершенно разные исследования, но та же проблема. Вы знаете, абстрактная проблема;) –

ответ

5

В коде 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.

+0

Спасибо x1000. Эта мысль даже не приходила мне в голову. Что касается переименованного ключа права, можете ли вы дать ссылку? В документации по-прежнему указывается 'collection-scope'. – Dov

+1

Изменение названия прав упоминается в таблице 3-4 [Ссылка на ключевые слова для прав доступа] (https://developer.apple.com/library/mac/#documentation/Miscellaneous/Reference/EntitlementKeyReference/EnablingAppSandbox/EnablingAppSandbox.html#//apple_ref/DOC/UID/TP40011195-СН4-SW18). – Tim

+0

@Tim Вы упомянули, что «необходимо иметь существующий (но пустой) файл, который будет содержать закладки с областью документа». Как следует знать местоположение, в котором пользователь впервые сохранит новый документ. Более того, как создать пустой файл в каком-либо месте с песочницей, а NSSavePanel не будет отображаться? – AmaltasCoder