Как я могу добавить возможности iCloud Documents в свое приложение без использования Xcode?

Мое приложение аварийно завершает работу с "Средство выбора документа, инициализирующее приложение, которое не имеет права iCloud", когда выполняется одна из следующих двух строк:

UIDocumentPickerViewController* documentPicker =
  [[UIDocumentPickerViewController alloc]
    initWithDocumentTypes:@[@"public.data"]
                   inMode:UIDocumentPickerModeImport];

UIDocumentMenuViewController *documentMenu =
  [[UIDocumentMenuViewController alloc]
    initWithDocumentTypes:@[@"public.data"]
                   inMode:UIDocumentPickerModeImport];

В Руководстве по программированию средства выбора документов говорится, что "прежде чем ваше приложение сможет использовать средство выбора документов, вы должны включить возможности документов iCloud в XCode".

Однако мое приложение не создано с помощью XCode: оно создано с использованием сторонних инструментов (кроссплатформенный инструментарий, Marmalade), поэтому я не могу этого сделать.

По-прежнему должна быть возможность включить возможности iCloud Documents для этого приложения вручную - коммутатор в iCloud просто автоматизирует процесс - но мои попытки сделать это не устранили сбой.

Что я пробовал до сих пор

Xcode отображает шаги, которые он выполняет при включении iCloud:

  1. Добавьте право "iCloud" к своему идентификатору приложения
  2. Добавьте право "iCloud Containers" к своему идентификатору приложения.
  3. Добавьте право "iCloud" в файл прав
  4. Ссылка CloudKit.framework

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

Я включил iCloud для своего идентификатора приложения:

Снимок экрана идентификатора приложения, показывающий, что iCloud включен

Я не уверен, нужно ли это для использования простых операций импорта и экспорта средства выбора документов, но я также настроил контейнер iCloud с идентификатором iCloud.com.[company].[app],

Я создал обновленный профиль обеспечения, который включает права iCloud:

Снимок экрана профиля обеспечения, показывающий, что служба iCloud включена

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

security cms -D -i /path/to/iOSTeamProfile.mobileprovision

Он включает в себя следующие записи:

<key>com.apple.developer.icloud-services</key>
<string>*</string>
<key>com.apple.developer.icloud-container-environment</key>
<array>
  <string>Development</string>
  <string>Production</string>
</array>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.icloud-container-development-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
  <string>iCloud.com.[company].[app]</string>
</array>

Marmalade использует этот профиль обеспечения для создания файла разрешений для приложения.

Я проверил сгенерированные права с помощью следующей команды:

codesign -d --ent :- [App.app]

Что дает следующий вывод:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>application-identifier</key>
  <string>[team-id].com.[company].[app]</string>
  <key>aps-environment</key>
  <string>development</string>
  <key>com.apple.developer.icloud-container-development-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.icloud-container-environment</key>
  <array>
    <string>Development</string>
    <string>Production</string>
  </array>
  <key>com.apple.developer.icloud-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.icloud-services</key>
  <string>*</string>
  <key>com.apple.developer.team-identifier</key>
  <string>[team-id]</string>
  <key>com.apple.developer.ubiquity-container-identifiers</key>
  <array>
    <string>iCloud.com.[company].[app]</string>
  </array>
  <key>com.apple.developer.ubiquity-kvstore-identifier</key>
  <string>[team-id].*</string>
  <key>get-task-allow</key>
  <true/>
  <key>keychain-access-groups</key>
  <array>
    <string>[team-id].com.[company].[app]</string>
  </array>
</dict>
</plist>

Тем не менее, приложение по-прежнему падает при каждом вызове функций.

Я также нашел это старое руководство по настройке iCloud в приложениях Marmalade. Кажется, что большинство шагов больше не являются необходимыми / возможными, но я последовал предложению добавить application-identifier ключ к моему Info.plist.

Что еще мне нужно сделать, чтобы добавить возможности iCloud Documents в мое приложение?

1 ответ

Решение

Мармелад порождает .xcent файл разрешений, используемый при подписании приложения путем копирования через "Права" dict из профиля обеспечения.

Проблема была вызвана значением, связанным с недокументированным ключом:

<key>com.apple.developer.icloud-services</key>
<string>*</string>

Это кажется действительным в профиле обеспечения, но недействительным при входе в приложение. Замена этих элементов в сгенерированном .xcent file с помощью следующего, а затем повторной подписи приложение устранило проблему:

<key>com.apple.developer.icloud-services</key>
<array>
  <string>CloudDocuments</string>
</array>

(Примечание: если вы также используете CloudKit, вам также необходимо добавить CloudKitstring к array .)

На практике мы исправили это, отредактировав мармелад sign_app.py Сценарий для использования предварительно подготовлен .xcent файл (скопировано из DerivedData каталог действующего приложения, которое мы создали с помощью Xcode) при подписании приложения:

В файле /Applications/Marmalade.app/Contents/s3e/deploy/plugins/iphone строка редактирования 557:

cmd += ['--entitlements', xcentfile.name]

... замена xcentfile.name с пути к заранее подготовленным .xcent файл.

Другие вопросы по тегам