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

Предоставление приложения вездесущего контейнера для iCloud Drive в iOS 8

Я разрабатываю приложение с поддержкой iCloud, где пользователи смогут импортировать и экспортировать файлы через iCloud Drive. При просмотре iCloud Drive, используя либо UIDocumentPickerViewController (iOS 8), либо Finder (OS X Yosemite), я могу видеть каталоги, созданные/принадлежащие другим приложениям с поддержкой iCloud-Drive, таким как Automator, Keynote или TextEdit.

Я хочу, чтобы наше приложение также отображало свой вездесущий каталог документов в iCloud Drive, но пока не смогло его выяснить. В некоторых из вышеперечисленных файлов приложений Info.plist я обнаружил этот ключ:

<key>NSUbiquitousContainers</key>
<dict>
    <key>com.apple.TextEdit</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

Эти ключи также документированы здесь, но я не нашел никакой другой документации по более широкой теме. Редактировать/Примечание:. Хотя он не содержит ответа на мои вопросы, Руководство по программированию для выбора документов является полезным ресурсом.

Я попытался добавить вышеупомянутые ключи/значения в наше приложение, но не видел никакого эффекта. Что я заметил/попробовал:

  • Для сторонних приложений контейнеры iCloud сконструированы следующим образом: iCloud.$(CFBundleIdentifier). Я не уверен, почему TextEdit использует только чистый идентификатор пакета, но для нашего идентификатора я пробовал оба подхода, то есть с префиксом iCloud. и без него. Я также признал, что вам нужно жестко закодировать идентификатор пакета (т.е. Не использовать iCloud.$(CFBundleIdentifier)), поскольку только значения PLIST, по-видимому, решаются во время сборки, но не с ключами.

  • Я добавил подкаталог программно (до <containerPath>/Documents), чтобы контейнер не был пустым. Однако это не имеет значения, поскольку все каталоги других приложений также были пустыми.

  • Некоторые приложения Apple, которые появляются в iCloud Drive, не имеют этих записей в своих Info.plist, например, Numbers и Pages.

  • iCloud настроен правильно, и я могу программно изучить контейнер ubiquity, используя URL-адрес, возвращаемый [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];.

  • Я зарегистрирован в учетной записи iCloud, где включен iCloud Drive. Я вижу содержимое iCloud Drive в UIDocumentPickerViewController.

  • Я использую симулятор iOS 8 beta 5 (и Yosemite beta 5 для просмотра каталога iCloud Drive на Mac) ( Изменить/Примечание:. Это в равной степени относится к бета-версии 6)

Вот как выглядит мой файл прав (только для соответствующих частей)

<key>com.apple.developer.icloud-container-identifiers</key>
<array>
    <string>iCloud.$(CFBundleIdentifier)</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
    <string>CloudDocuments</string>
</array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array/>

Я установил это с помощью интерфейса Xcode в разделе "Возможности". Я не понимаю, почему последний ключ не имеет записи, но добавление <string>iCloud.$(CFBundleIdentifier)</string> не помогает. Вместо этого он вызывает Xcode в интерфейсе возможностей, поэтому я удалил его. Редактировать/Примечание: В Xcode beta 6 это исправлено, т.е. необходимо установить идентификатор контейнера для ubiquity, и Xcode может исправить это для вас.

Оригинальные вопросы: Итак... это ошибка? Разве это еще не работает? Я делаю это неправильно? Я не мог найти известную проблему в примечаниях к выпуску.

Edit:

Еще две вещи, которые я пробовал:

  • Добавление ключа (необязательного) NSUbiquitousContainerName (+ значение) в словарь для конкретных контейнеров, как это было предложено Erikmitk.

  • Добавление только ключа/значения NSUbiquitousContainerIsDocumentScopePublic в корневой словарь PLIST, а не в словарь для конкретного контейнера, как это сделано в одном из примеров приложений WWDC (ищите NewBox).

4b9b3361

Ответ 1

Уловкой является вызов [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; (или с другим идентификатором контейнера, если он не является значением по умолчанию), по крайней мере, один раз (не для запуска, а предположительно для каждой версии или при изменении одной из соответствующих записей PLIST), чтобы инициализировать каталог. Я считаю, что этот шаг необходимо сочетать с увеличением номера версии пакета, как это предлагается в ответе roop.

Я замечаю, что мой вопрос, возможно, был путаным в этом отношении, поскольку я упоминал, что я могу смотреть в каталог документов * программно с использованием рассматриваемого API. Тем не менее, я удалил этот код из приложения позже, возможно, прежде чем все остальные настройки будут исправлены. Я не буду писать в каталог документов напрямую, только через Document Picker. Поэтому не нужно было получать URL-адрес.

Если вам просто нужен подборщик документов для чтения/хранения файлов из/в каталогах iCloud Drive или других приложений, нет необходимости звонить URLForUbiquityContainerIdentifier:. Только если вы хотите, чтобы ваше приложение имело свой собственный контейнер для повсеместности (и потенциально выставлял его на iCloud Drive и Document Picker), необходимо выполнить шаги, указанные в исходном сообщении, и вызов URLForUbiquityContainerIdentifier:.

* При упоминании каталога документов я всегда ссылаюсь на тот, который находится в контейнере ubiquity, а не на локальном.

Ответ 2

Когда вы редактировали Info.plist, возможно, вы забыли поднять номер версии пакета? Это требование согласно сеансу WWDС# 234.

Ответ 3

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

  • Добавьте параметр NSUbiquitousContainers в мой файл Info.plist в соответствии с документацией здесь https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html. Вот соответствующий код:

    <dict>
        <key>NSUbiquitousContainers</key>
        <dict>
            <key>iCloud.com.example.MyApp</key>
            <dict>
            <key>NSUbiquitousContainerIsDocumentScopePublic</key>
            <true/>
            <key>NSUbiquitousContainerSupportedFolderLevels</key>
            <string>Any</string>
            <key>NSUbiquitousContainerName</key>
            <string>MyApp</string>
        </dict>
    </dict>
    
  • Важно! Затем я изменил приведенное выше строковое значение NSUbiquitousContainerSupportedFolderLevels от Any до One

    <key>NSUbiquitousContainerSupportedFolderLevels</key>
    <string>One</string>
    
  • Далее и, наконец, мне пришлось изменить CFBundleVersion на более высокую версию. Я также столкнулся с CFBundleShortVersionString и с новой версией.

Построен и запущен, и после этого папка с иконкой моих приложений появилась правильно в iCloud Drive! Надеюсь, это поможет!

Ответ 4

Кажется, изменение CFBundleVersion позволит ему работать.

Я думаю, вы можете попробовать. Я получил это от Форумы разработчиков Apple.

Надеюсь, что эта работа для вас.

Ответ 5

В моем случае (Xcode 7 и iOS 9) единственное, что заставило его работать после нескольких попыток, было просто использовать новый идентификатор пакета (вам не нужно менять идентификатор контейнера облака, просто убедитесь, что выберите контейнер, который вы хотите использовать в Центре разработчиков Apple Developer, и укажите в Xcode собственный контейнер вместо стандартного).

Фактически, это означает, что при первом запуске приложения необходимо настроить раздел NSUbiquitousContainers в файле info.plist. Если вы установите его впоследствии как второй шаг, это не сработает...

Ответ 6

После того, как все это утро, прочитав все сообщения, внеся все изменения, ключевая вещь, которая, наконец, работала для меня, была объявлена ​​как Еще один Code Maker, изменив идентификатор пакета. Я думаю, что как только он создаст контейнер для пакета, вы не сможете вернуться и изменить видимость его, чтобы он появился в Finder. Я пробовал все разные значения info.plist, но ничего не работал, пока я не перешел на новое имя пакета и не заставил систему создать новую. Кстати, я не видел, чтобы это отмечалось где угодно, но имя пакета, имя NSUbiquitousContainer и имя NSUbiquitousContainerName могут быть разными - это то, что я сделал в моем случае. Проведя так много времени на это, я решил, что я продолжу и поставлю пример простого примера на GitHub, если у кого-то все еще есть проблемы с отладкой их папки iCloud, появляющейся в Finder, - вы можете найти ее здесь. Все необходимые шаги описаны в README.

Ответ 7

Не удалось найти документацию, но пробную версию и ошибку я обнаружил, что:

[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"com.apple.CloudDocs"]; 

Дает вам базовый URL для диска, как показано в сборщике. Используя этот базовый URL-адрес, я смог сохранить файлы в своем приложении и увидеть его на диске iCloud в Yosemite.

Изменить 14.8.14

Я попробовал настройки plist:

<key>NSUbiquitousContainers</key>
<dict>
    <key>iCloud.net.redacted.docTest</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

В моем маленьком тестовом приложении "docTest" оно действительно раскрывает пустой каталог "Документы" в Yosemite и в сборщике документов.

Снимок экрана http://spring-appstudio.com/picker-view.png

Ответ 9

Такая же проблема возникла в моем приложении OSX.

Кажется, что настройка NSUbiquitousContainers работает только во время создания контейнеров iCloud. Поэтому я попытался с новым идентификатором Apple (для подготовки чистой среды iCloud), он будет работать.

Ответ 10

Просто хотел подчеркнуть одно из открытий OP, которое зафиксировало это для меня:

Я также признал, что вам нужно жестко закодировать идентификатор пакета (т.е. не использовать iCloud.$(CFBundleIdentifier)), поскольку только значения PLIST, по-видимому, решаются во время сборки, но не с ключами.

Вам нужно жестко закодировать идентификатор пакета. Также обновите версию.

(Я не заметил этого в вопросе, пока не просмотрел все ответы).

Ответ 11

Я знаю, что это старый поток, но на всякий случай кто-то сталкивается с одной и той же проблемой: единственный способ заставить мою папку Container быть видимой в iCloud Drive (после попытки всех вышеперечисленных предложений) состоял в том, чтобы создать мое приложение временный файл в папке "Документы". Как только я это сделал, папка контейнера (и файл, который я создал) появилась на моем Mac. Если это действительно так, я должен создать файл, чтобы сделать эту папку видимой, тогда это будет немного раздражать, потому что мое приложение является только для чтения (только чтение файлов, добавленных пользователем в папку контейнера). Папка контейнера должна быть видимой, как только приложение будет запущено в первый раз. Думаю, мне придется обнаружить первый запуск.