Продолжаем делиться своей практикой и переводами статей, которые могут быть полезны мобильному разработчику. В прошлых статьях мы разобрали инструменты тестирования и оптимизацию внедрения зависимостей в Android, а сейчас рассмотрим одно из нововведений в iOS 13 – поддержку многооконного режима и разделение AppDelegate (жизненный цикл и настройка приложения) и SceneDelegate (отображение приложения).
От автора: Ещё до Xcode 11, при создании нового проекта вы знали, что по умолчанию создаются некоторые файлы, такие как AppDelegate.swift, ViewController.swift и StoryBoard, а также некоторые другие. Но в Xcode 11 вы могли заметить, что наряду с файлами по умолчанию, указанными выше, создается новый файл – SceneDelegate.swift.
Сначала вам может быть непонятно, что это за файл, для чего он создан и как использовать SceneDelegate при разработке приложения. Но давайте попробуем понять разницу между AppDelegate и SceneDelegate.
AppDelegate будет отвечать за жизненный цикл и настройку приложения. SceneDelegate будет отвечать за то, что отображается на экране (Windows или Scenes), и управлять способом отображения вашего приложения.
Зоны ответственности AppDelegate и Scene Delegate
AppDelegate
Даже в iOS 13 AppDelegate по-прежнему является основной точкой входа для приложения. Методы AppDelegate вызываются для событий жизненного цикла уровня приложения. В AppDelegate.swift по умолчанию есть три метода, которые Apple считает важными. Давайте их рассмотрим:
func application(_:didFinishLaunchingWithOptions:) -> Bool
func application(_:configurationForConnecting:options:) -> UISceneConfiguration
func application(_:didDiscardSceneSessions:)
func application(_:didFinishLaunchingWithOptions:) -> Bool
Этот метод вызывается ближе к концу запуска приложения, по завершении его настройки. В предыдущих версиях iOS 13 мы могли использовать этот метод для настройки объекта UIWindow и назначения экземпляра ViewController объекту UIWindow, чтобы он отображался на экране. Начиная с iOS 13, если в вашем приложении есть сцены, то AppDelegate больше не отвечает за их обработку и перемещается в SceneDelegate.
func application(_:configurationForConnecting:options:) -> UISceneConfiguration
Этот метод вызывается каждый раз когда приложению требуется отобразить новую сцену или окно. Этот метод не вызывается при запуске приложения, а только тогда, когда необходимо получить новую сцену или новое окно.
func application(_:didDiscardSceneSessions:)
Этот метод вызывается каждый раз, когда пользователь избавляется от сцены, например, удаляя ее из окна многозадачности, или если от нее избавляются программно.
Если в тот момент, когда пользователь избавляется от сцены, приложение не работает в момент, то этот метод будет вызван вскоре после вызова метода (_:didFinishLaunchingwithOptions:)
для каждой отброшенной сцены.
Помимо этих методов, AppDelegate по-прежнему может обрабатывать внешние службы, такие как регистрация push-уведомлений, определение местоположения, завершение работы приложения и многое другое.
SceneDelegate
Начиная с iOS 13, SceneDelegate берет на себя некоторые функции AppDelegate. В частности, UIWindow из AppDelegate теперь связан с UIScene в SceneDelegate. Приложение может иметь более одной сцены, которая в основном обрабатывает интерфейс и контент приложения. Итак, SceneDelegate отвечает за то, что отображается на экране в плане пользовательского интерфейса и данных.
Методы по умолчанию, которые можно увидеть в SceneDelegate:
scene(_:willConnectTo:options:)
sceneDidDisconnect(_:)
sceneDidBecomeActive(_:)
sceneWillResignActive(_:)
sceneWillEnterForeground(_:)
sceneDidEnterBackground(_:)
Эти методы похожи на те, что использовались в AppDelegate в iOS 12 и более ранних версиях. Для чего предназначен каждый метод, можно понять, посмотрев на названия, разница только в терминологии.
scene(_:willConnectTo:options:)
Это первый метод, вызываемый в жизненном цикле UISceneSession. Этот метод создает новый UIWindow, устанавливает контроллер корневого представления и делает это окно ключевым для отображения.
sceneWillEnterForeground(_ :)
Этот метод вызывается, когда сцена вот-вот начнется - например, когда приложение запускается в первый раз или при переходе из фона к переднему плану.
sceneDidBecomeActive(_ :)
Этот метод вызывается сразу после метода WillEnterForeground, и здесь сцена настроена, видна и готова к использованию.
sceneWillResignActive(_ :) и sceneDidEnterBackground(_ :)
Эти методы вызываются, когда приложение уходит в фон.
sceneDidDisconnect(_ :)
Это самый интересный из всех методов. Когда сцена отправлена в фон, iOS может полностью сбросить её, чтобы освободить ресурсы. Это не означает, что приложение остановлено или не запущено, просто сцена отключена от сессии и неактивна. iOS может решить повторно подключить эту сцену к сеансу, когда пользователь снова выведет эту сцену на передний план. Этот метод можно использовать для сбрасывания тех ресурсов, которые больше не используются.
Вывод
Основная причина, по которой Apple добавила UISceneDelegate в iOS 13, заключалась в том, чтобы создать хорошую точку входа для многооконных приложений. Из приведенной выше теории вы могли понять роли AppDelegate и SceneDelegate в iOS 13 и их события жизненного цикла. AppDelegate отвечает за обработку событий уровня приложения, таких как запуск приложения, а SceneDelegate отвечает за события жизненного цикла сцены, такие как создание сцены, разрушение и восстановление состояния UISceneSession.
Спасибо за внимание! Надеемся, что материал был вам полезен.
Авторские материалы для mobile-разработчиков мы также публикуем в наших соцсетях – ВКонтакте и Telegram.