В тестовой цели iOS UI отсутствует право доступа icloud-services

У меня есть приложение, использующее iCloud. Это прекрасно работает.

Теперь я попытался написать тест пользовательского интерфейса, который сначала проверяет, доступна ли учетная запись iCloud, т.е. что пользователь вошел в систему iCloud и iCloud включен для приложения.

Для этого я попытался позвонить (CloudKit импортирован)

let container = CKContainer(identifier: kICloudContainerID)
container.accountStatus() { (status, error) in
  // …
}  

Однако как только я пытаюсь получить доступ к CKContainer (1-я строка), я получаю сообщение об ошибке

The application is missing required entitlement com.apple.developer.icloud-services
(null)

Конечно, в моем приложении установлены права доступа iCloud, но такие права нельзя установить для тестовой цели.

Я прочитал этот пост. Предлагаемые решения (отключение точек останова, переключение возможностей iCloud, очистка прав для подписи кода) не работали.

Есть идеи, как решить эту проблему?

РЕДАКТИРОВАТЬ:

Для тестирования я создал новое приложение для одного просмотра с включенными тестами пользовательского интерфейса.
В целевом приложении я включил только CloudKit:
 введите описание изображения здесь

В делегате приложения я импортировал CloudKit и получил доступ к CKContainer:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let container = CKContainer(identifier: "iCloud.com.zeh4soft.EntitlementUITest")
    return true
}  

Это работает.

В тестах пользовательского интерфейса я также импортировал CloudKit и добавил ту же строку:

func testExample() {
  let container = CKContainer(identifier: "iCloud.com.zeh4soft.EntitlementUITest")
}  

Это не работает, но дает ту же ошибку:
< img src = "https://i.stack.imgur.com/HEVVC.png" alt = "введите описание изображения здесь">


person Reinhard Männer    schedule 11.04.2019    source источник


Ответы (1)


Я связался с Apple, и они нашли решение для устройства, но не для симулятора.
Я сделал следующие шаги:

Настройте в Xcode совершенно новый проект приложения для единого просмотра и включите тесты пользовательского интерфейса. Назовите это «EntitlementUITest». Это создаст в навигаторе проекта папку «EntitlementUITestUITests».

Выберите в этой папке «EntitlementUITestUITests.swift».
Есть функция testExample(). Добавьте в эту функцию строку

    let _   = CKContainer(identifier: "iCloud.com.yourid.EntitlementUITest")

yourid - это, например, название вашей компании.
Это утверждение вызывает ошибку времени выполнения, если проект не был подготовлен, как описано ниже.

Выберите проект в навигаторе проекта.
Откроется дополнительная панель с проектом и целями.
Есть 2 цели: основная цель «EntitlementUITest» и цель теста пользовательского интерфейса «EntitlementUITestUITests».
Выберите основную цель «EntitlementUITest».
В верхней панели окна справа от панели выберите «Возможности». Вы увидите, что можете выбрать использование iCloud.

Теперь выберите тестовую цель «EntitlementUITestUITests». На верхней панели теперь нет «Возможностей». Это означает, что настройка, которая позволяет вашим UI-тестам использовать iCloud, намного сложнее и должна выполняться вручную.

Во-первых, нужен файл прав, в котором указаны возможности, которые приложение хочет использовать. Я вручную создал следующий файл (фактически, я скопировал файл полномочий основной цели и отредактировал его):

<?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>aps-environment</key>
    <string>development</string>
    <key>com.apple.developer.icloud-container-identifiers</key>
    <array>
        <string>iCloud.com.yourid.EntitlementUITest</string>
    </array>
    <key>com.apple.developer.icloud-services</key>
    <array>
        <string>CloudKit</string>
    </array>
</dict>
</plist>  

Я добавил этот файл в проект.

Чтобы разрешить целевому объекту тестирования пользовательского интерфейса использовать iCloud, теперь необходимо выполнить несколько действий в центре разработки.

В своем веб-браузере откройте центр разработки и откройте там «Сертификаты, идентификаторы и профили».

Тестовая цель рассматривается как новое приложение. Таким образом, ему нужен отдельный идентификатор приложения.
Откройте идентификаторы приложений и добавьте новый идентификатор «EntitlementUITestUITests».
Это должен быть «явный идентификатор приложения», который использует идентификатор пакета вашей тестовой цели, здесь

com.yourid.EntitlementUITest.  

Включите iCloud и Push-уведомления.
Я не уверен, требуются ли Push-уведомления, но Apple сказала мне сделать это. Возможно, вы можете опустить его в файле прав и здесь. Если он присутствует, убедитесь, что для службы push-уведомлений указан действительный сертификат.
При включении iCloud убедитесь, что iCloud.com.yourid.EntitlementUITest - единственный выбранный среди назначенных контейнеров iCloud.

Затем создайте новый профиль обеспечения разработки (тот, который использует ваш сертификат разработчика iOS) и свяжите его с com.yourid.EntitlementUITestUITests.
Загрузите профиль.

Вернувшись в Xcode, снова выберите цель «EntitlementUITestUITests» на вкладке «Общие».
В разделе «Подписание» снимите флажок «Автоматически управлять подписанием», поскольку это не работает.
В «Подписание (отладка)» выберите в раскрывающемся меню «Профиль подготовки» чтобы импортировать только что загруженный профиль. Это также будет выбрано в разделе «Подписание (выпуск)».

Теперь проект должен быть собран для тестирования без ошибок.

Запустите testExample. Теперь он должен работать без ошибок времени выполнения.

Заключение:
Можно получить доступ к CKContainer в тесте пользовательского интерфейса, но это невероятно сложно.
Почему этот процесс не так прост, как с основными целями?
Может быть, слишком меньше разработчиков пользовательского интерфейса тестирует свой iCloud приложения, иначе было бы написано больше запросов на улучшение Xcode ...

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

person Reinhard Männer    schedule 22.05.2019