watchOS 2: установка свойств на начальном контроллере интерфейса

Начиная с watchOS 2, у нас есть объект ExtensionDelegate, который аналогичен UIApplicationDelegate (реагирует на события жизненного цикла приложения).

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

Согласно docs, свойство rootInterfaceController на WKExtension возвращает исходный контроллер:

Контроллер корневого интерфейса расположен в основной раскадровке приложения, и с ним связан объект Main Entry Point. WatchKit отображает контроллер корневого интерфейса во время запуска, хотя приложение может представить другой контроллер интерфейса до завершения последовательности запуска.

Поэтому я пробую в ExtensionDelegate следующее:

func applicationDidFinishLaunching() {
    guard let initialController = WKExtension.sharedExtension().rootInterfaceController else {
        return
    }

    initialController.dataStore = DataStore()
}

Несмотря на то, что отображается правильный интерфейсный контроллер, rootInterfaceController в этот момент равен нулю. Интересно, что если я запрашиваю то же свойство в willActivate() моего контроллера интерфейса, свойство устанавливается правильно.

В приложении для iOS вы уже можете получить контроллер корневого представления в applicationDidFinishLaunching(), и я подумал, что он должен работать так же для watchOS.

Есть ли способ установить свойства на моем контроллере интерфейса до его отображения (извне)? Это ошибка?

Большое спасибо за ответ!


person József Vesza    schedule 28.09.2015    source источник
comment
Вы когда-нибудь находили причину этого? @ józsef-vesza   -  person Wilmar    schedule 01.12.2015
comment
@Wilmar, к сожалению, нет. Кажется, что rootInterfaceController на данном этапе равно нулю, поэтому я закончил тем, что создал экземпляры своих свойств в подклассах контроллера интерфейса. Не очень хорошо, но это лучшее, что у меня есть на данный момент. : /   -  person József Vesza    schedule 01.12.2015
comment
Мм, понятно. Я добавил dispatch_after в свой код, установил его на 1 секунду, и тогда свойство rootInterfaceController имело ожидаемое значение. Довольно неприятно. @ józsef-vesza   -  person Wilmar    schedule 01.12.2015
comment
Хм. Интересно. Я не хотел добавлять больше задержек (время запуска уже довольно велико), но это интересная информация, спасибо! Да, это расстраивает, я ожидал, что делегат расширения будет вести себя как делегат приложения в iOS.   -  person József Vesza    schedule 01.12.2015
comment
Договорились о времени загрузки. Я добавил его только для того, чтобы увидеть, установится ли в конечном итоге значение. Также пришлось перестроить мою логику делегирования, чтобы она не зависела от обратных вызовов. @ józsef-vesza   -  person Wilmar    schedule 01.12.2015
comment
Я только что столкнулся с этими двумя. Иногда я вижу, что applicationDidFinishLaunching срабатывает дважды, а во втором вызове rootInterfaceController больше не равно нулю. Очень странный. Вы подали радар? Я был бы счастлив обмануть это.   -  person Jeff V    schedule 10.01.2016


Ответы (1)


Вы можете переместить свой код в applicationDidBecomeActive.

На этой странице описаны состояния приложений для часов. Когда вызывается applicationDidFinishLaunching, приложение находится в неактивном состоянии.

https://developer.apple.com/library/watchos/documentation/WatchKit/Reference/WKExtensionDelegate_protocol/index.html

person Drewf    schedule 02.10.2015
comment
К сожалению, я уже пробовал это, но WKExtension.sharedExtension().rootInterfaceController nil во всех обратных вызовах делегата расширения. - person József Vesza; 02.10.2015
comment
Работал у меня - раньше WKExtension.sharedExtension().rootInterfaceController не было. - person Joshua C. Lerner; 28.01.2019