WatchKit: не удалось найти интерфейс класса контроллера

Я попробовал добавить контроллер интерфейса в раскадровку, установив свой пользовательский класс в подкласс WKInterfaceController, запустил приложение в симуляторе и перешел к указанному интерфейсу.

Когда я это сделаю, я получаю следующую ошибку:

Ошибка WatchKit - не удается найти интерфейс класса контроллера "TestController" для создания экземпляра

Если я попытаюсь взаимодействовать с контроллером (например, попробуйте запустить его действие кнопки), я получаю следующую ошибку:

  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: (null) не найден
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: 7120004 не найден.

Я попробовал установить имя модуля, как рекомендовано в этом ответе, но это все равно дает мне следующие ошибки:

  • Ошибка WatchKit - не удается найти интерфейс класса контроллера '_TtC29myWatchApp_WatchKit_App19TestController' для создания экземпляра
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: (null) не найден
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: 6E20004 не найден.

Ответы

Ответ 1

Я получил эту ошибку после переименования цели WatchKit, но, наконец, понял: если вы переименуете цели WatchKit, вам придется пройти через интерфейсы в Interface Builder и убедиться, что имена модулей для каждого из них также переименованы.

Вы можете сделать это, выбрав контроллер интерфейса, щелкнув идентификатор инспектора (или команду-option-3), удалив имя модуля, затем откройте вкладку. Он будет автоматически заполнен новым целевым именем. Это сделало это для меня!

Ответ 2

Эта ошибка возникла для меня, потому что я неправильно обрабатывал сообщение didDeactivate. Мой деактивированный контроллер все еще получал сообщения через MMWormhole. Как только я разорвал это соединение, ошибка исчезла. Оказывается, в симуляторе все деактивированные интерфейсные контроллеры разворачиваются в памяти, поэтому вам нужно внимательно следить за тем, чтобы они не получали никаких сообщений. Я не знаю, случается ли это на самом часовом, но, конечно, мы должны это делать.

Ответ 3

Я потратил слишком много времени на эту проблему, но, наконец, понял, что это такое. Apple Watch имеет в основном два шаблона навигации:

Иерархическая:

[self pushControllerWithName:@"controllerName" context:nil];

Страница на основе:

[[self class] reloadRootControllersWithNames:@[@"controller1",@"controller2"] contexts:nil];

В соответствии с яблоком:

Вы не можете комбинировать иерархические и стили интерфейса на основе страниц. Во время разработки вы должны выбрать стиль, который наилучшим образом соответствует вашему контенту и дизайну для этого стиля.

Итак, проблема в том, что я смешивал оба, и это приводит к поведению undefined, например:

*********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: (null) не найден

Надеюсь, это поможет другим разработчикам.

EDIT:

Просто предложение, которое работало для меня как обходной путь, при использовании навигации по страницам вы все равно можете представить модальные контроллеры (просто говоря):

[self presentControllerWithName:@"controllerName" context:nil];

Ответ 4

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

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

Изучение исходного кода раскадровки показывает один способ обхода.

Интерфейсные контроллеры, которые работают, выглядят следующим образом:

<controller id="AgC-eL-Hgc" customClass="InterfaceController" 
  customModule="myWatchApp_WatchKit_App" customModuleProvider="target">

Контроллеры интерфейса, которые не работают, не имеют атрибутов customModule и/или customModuleProvider.

Поэтому обходным путем является вручную добавить эти отсутствующие атрибуты в файл раскадровки, щелкнув его правой кнопкой мыши и выбрав Открыть как > Исходный код.

Долгосрочным решением может быть исправление раскадровки, чтобы пользовательские классы отображались в раскрывающихся списках (см. связанный вопрос для некоторых возможных исправлений).

Update:

Другие интерфейсные контроллеры, которые также используют customModule="myWatchApp_WatchKit_Extension" (обратите внимание на разницу _Extension vs. _App) и не нуждаются в атрибуте customModuleProvider.

Ответ 5

Для меня это кажется ложным отрицательным. Я попробовал все предлагаемые решения, но потом доказал, что это ошибка Apple, создав новый проект Apple Kit, сделав одно изменение в Glance (добавив изображение) и получив ошибку. Я зарегистрировал следующую ошибку с Apple в своем репортере ошибок.

Название

Получать clientIdentifier для интерфейсаControllerID не найден, когда переход на взгляд

Описание

Я получаю следующую ошибку, которая представляется ложным отрицательным при переходе на первый взгляд в проекте watchOS 2.0. Я воспроизвел это, создав новый проект Apple Kit, сделав одно изменение Взгляд (добавление изображения) и получение ошибки.

Шаги по воспроизведению

  • Очистить все данные как в симуляторах watch, так и iOS.
  • В XCode создайте новое приложение WatchKit, включающее в себя сложность и взгляд.
  • Запустите и не увидите проблем.
  • Добавьте png к вашим изображениям.
  • Добавьте представление UIImageView в интерфейс разработчика интерфейсов.
  • Запустите расширение в симуляторе часов.
  • Включите просмотр в приложении сопутствующего устройства iOS.
  • Перейдите к обзору в симуляторе часов.
  • Обратите внимание на следующую ошибку в вашем журнале.

2015-07-16 08: 35: 10.663 ресторан-отчет WatchKit App Расширение [78301: 2211560] *********** ОШИБКА - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier для интерфейсаControllerID: 3118001E не найден

Ожидаемый результат

В журнале

не должно появляться ложных негативов

Фактический результат

В логе

появляется ложный негатив,

Смотреть версию ОС (сборка)

2.0 (13S5293f)

Они дали мне ошибку id 21853566.

Ответ 6

Я думаю, вы забыли использовать storyboardID для своего класса. Это то, что я получаю от вашей ошибки.

enter image description here

Ответ 7

У меня была эта проблема, когда я переименовал цель WatchKit. Когда я переименовал его, ошибка исчезла.

Ответ 8

Лучший способ сделать push/pop-контроллер - запустить этот фрагмент кода в основной поток, чтобы:

dispatch_async(dispatch_get_main_queue(), ^{
     [self pushControllerWithName:@"controllerIdentifier" context:data];
});

dispatch_async(dispatch_get_main_queue(), ^{
     [self popToRootController];
});

dispatch_async(dispatch_get_main_queue(), ^{
     [self popController];
});

Документация Apple описывает три метода:

Всегда вызывайте этот метод из основного потока расширений WatchKit.

Ответ 9

Вам нужно проверить, что контроллер просмотра находится в вашем источнике компиляции: Выберите "Проект" > "Выбор сторожевого узла" > "Фазы сборки" > "Скомпилировать источники"

Ответ 10

Это не то, что вы делаете неправильно. Это уже известная проблема. См. Мой ответ здесь. Пожалуйста, обманите следующие radar на Apple Система отчетов об ошибках чтобы повысить приоритет, чтобы зафиксировать это.

Ответ 11

У меня были такие же проблемы после недавнего выпуска 8.2. Я должен был перейти к каждому из моих интерфейсных контроллеров и настроить свой собственный модуль класса на все, что было показано как опция или "none".

Ответ 12

У меня возникла эта проблема, когда я ошибочно установил идентификатор контроллера корневого интерфейса. Когда я удаляю идентификатор, это предупреждение исчезло.

введите описание изображения здесь

Ответ 13

Контроллеры Имя модуля должно быть тем же именем, что и имя корневого каталога Project (название значка документа Xcode слева вверху).

введите описание изображения здесь

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

Btw, если вы новичок или не уверены, что я думал, что Id бросил это, потому что вы могли подумать, что ваш класс ошибается или что-то в этом роде. Ваш контроллер динамического интерфейса не должен указывать на класс Xcode NotificationController.swift по умолчанию. Конечно, вы можете создать пользовательский класс, т.е. FriendRequestNotificationController

Для устранения неполадок вы можете добавить этот код в метод awakeWithContext, чтобы узнать, какие контроллеры имеют какие ID.

override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)
    if let vcID = self.valueForKey("_viewControllerID") as? NSString {
        print("Controller: \(vcID)")
    }

    // Configure interface objects here.
}