iOS 15 принесла нам много нововведений. Среди них есть системная фича Prewarming, позволяющая “прогревать” наши приложения, чтобы сократить время их запуска. Что-ж, давайте разберемся, как это работает.
Как работает по версии документации Apple:
В iOS 15 и более поздних версиях система может, в зависимости от состояния устройства, предварительно разогреть ваше приложение — запустить незапущенные процессы, чтобы сократить время ожидания пользователя до того, как приложение станет пригодным для использования. Для дополнительной информации смотрите ролик WWDC. Система прогреет ваше приложение до состояния паузы. Если у вас есть вызываемый код до UIApplicationMain() и он использует доступ к ресурсам — они могут быть недоступны. Все.
Возьмем ключевые тезисы из того, что нам предоставляет Apple, и пойдем более детально разбираться, как это работает и что в действительности вызывается во время запуска/прогрева/запуска после прогрева.
Как работает на самом деле:
Для начала разберемся с процессами, на которые нам необходимо обратить внимание:
- dasd — демон планировщик для фоновых задач
- runningboardd — участник жизненного цикла всех приложений
- SpringBoard — приложение, отвечающее за главный экран в iOS. С него запускаются и загружаются все установленные приложения.
Что происходит под капотом системы во время запуска/прогрева/запуска после прогрева, кратко:
Запуск:
- SpringBoard принимает ивент о нажатии на иконку
- SpringBoard запрашивает бутстрап для процесса нашего приложения
- runningboardd исполняет запрос о запуске
- Куча системных вызовов про вычисление состояния/выделения памяти/регистрации
- Приложение загружает кеш/цепляется к нужным ему процессам
- SpringBoard устанавливает соединение с нашим приложением
- runningboardd сообщает, что все готово
- Приложение делает пару приседаний и запускается
- Закрываем приложение
- SpringBoard закрывает все соединения
- Системные вызовы чистят за собой память/процессы/прочее
- runningboardd сообщает dasd, что приложение закрылось
Прогрев:
- runningboardd получает ивент DAS Prewarm launch от dasd, что необходимо прогреть приложение
- SpringBoard запускает приложение в background
- runningboardd производит необходимые манипуляции
- Приложение подключается к процессам
- Если в приложении используются AppDelegate и SceneDelegate:
Инициализируется AppDelegate
Вызываются методы UIApplicationDelegate
(willFinishLaunchingWithOptions, didFinishLaunchingWithOptions)
Состояние UIApplication.State == .background - Если в приложении используется только AppDelegate:
Инициализируется AppDelegate
НЕ вызываются методы UIApplicationDelegate - SpringBoard устанавливает состояние для приложения Suspended
Запуск после прогрева:
- SpringBoard принимает ивент о нажатии на иконку
- SpringBoard активирует сцену приложения
- runningboardd высчитывает состояние приложения
- SpringBoard устанавливает состояние для приложения Running
- Если в приложении есть AppDelegate и SceneDelegate:
Приложение инициализирует SceneDelegate, вызывает методы UIWindowSceneDelegate(willConnectTo) - Если в приложении используется только AppDelegate:
Вызываются методы UIApplicationDelegate
Если у вас в приложении AppDelegate и SceneDelegate:
- Прогрев будет всегда инициализировать AppDelegate и его переменные
- Прогрев запускает методы UIApplicationDelegate, при этом UIApplication.State будет всегда == .background, будь то прогрев или обычный запуск — имейте это ввиду
- Запуск после прогрева инициализирует SceneDelegate и его переменные
- Запуск после прогрева запускает методы только UIWindowSceneDelegate
Если у вас в приложении только AppDelegate:
- Прогрев будет всегда инициализировать AppDelegate и его переменные
- Прогрев не запускает методы UIApplicationDelegate
Вывод
Прогрев приложения действительно работает, и знание, как конкретно он это делает и что он при этом запускает, поможет обуздать этот механизм. Чем чаще вы запускаете приложение, тем быстрее оно прогреется, примерное время попадания в пул прогрева — от 2 до 25 минут. Если у вас в приложении фантомные краши/разлогины и прочие непонятные вещи, имеет смысл проверить, как обстоят дела с прогревом. На симуляторе прогрева нет. Для прогрева не обязательно блокировать устройство и откладывать его на N минут.
Как самому посмотреть?
Для заинтересованных более детально посмотреть, что вообще происходит— проект на гитхабе.
Смотреть логи с девайса необходимо через системную консоль.
Полные логи выглядят примерно вот так, но оставим их для самых искушенных:
Упрощенные логи, использование только AppDelegate:
Упрощенные логи, использование AppDelegate и SceneDelegate:
Почитать:
- https://www.reddit.com/r/jailbreak/comments/f5cab6/question_what_is_dasd/
- https://eclecticlight.co/2019/11/09/how-runningboard-tracks-every-app-and-manages-some/
- https://ru.wikipedia.org/wiki/SpringBoard
- https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence#3894431
- https://github.com/nst/iOS-Runtime-Headers/blob/master/PrivateFrameworks/FrontBoard.framework/FBWorkspace.h
- https://support.apple.com/ru-ru/guide/console/cnsl1012/1.1/mac/11.0