Понимание роли делегатов приложений и делегатов сцены в Ios
Понимание роли делегатов приложений и делегатов сцены в разработке iOS
С самых ранних версий iOS протокол UIApplicationDelegate был основой управления жизненным циклом приложений iOS. Однако внедрение поддержки нескольких окон в iOS 13 коренным образом изменило то, как разработчики обрабатывают пользовательские интерфейсы. Apple представила протокол UISceneDelegate, чтобы отделить обязанности по управлению приложениями от управления каждым окном. Понимание точных ролей этих двух делегатов имеет важное значение для создания современных приложений для iOS с несколькими окнами — будь то таргетинг на iPhone, iPad или Mac Catalyst. Эта статья обеспечивает всестороннее исследование обоих делегатов, их методов жизненного цикла, как они взаимодействуют и передовой практики для их эффективного использования.
Что такое делегат приложения?
Делегат приложений является точкой входа и центральным координатором приложения iOS. Он соответствует протоколу и отвечает за обработку событий приложений высокого уровня, которые влияют на все приложение. Эти события включают запуск приложения, прекращение, предупреждения памяти, фоновый вывод и регистрацию удаленных уведомлений. Объект Делегата приложений автоматически инстанцируется системой при запуске и остается живым в течение всего процесса.
Основные методы жизненного цикла
Делегат приложений определяет несколько критических методов, которые система вызывает в ответ на изменения состояния приложения:
- — Называется после запуска приложения. Здесь вы инициализируете сторонние SDK, настраиваете стеки основных данных, настраиваете глобальный внешний вид и восстанавливаете состояние приложения. указывает, что приложение не может обрабатывать URL или активность, которая вызвала запуск.
- — При переходе приложения из неактивного в активное состояние используется для возобновления приостановки задач, обновления пользовательского интерфейса или перезапуска анимации.
- — Называется, когда приложение собирается стать неактивным (например, входящий телефонный звонок, пользователь нажимает кнопку блокировки). Сохранить состояние, приостановить игры и уменьшить использование ресурсов.
- — Отправлено, когда приложение перемещается в фоновое состояние. Выполняйте окончательную очистку, высвобождайте общие ресурсы и планируйте фоновые задачи.
- — Называется непосредственно перед возвращением приложения на передний план после его фонового изменения.
- — Называется, когда приложение вот-вот будет закрыто. Сохранить критические данные и выпустить ресурсы. Примечание: это не называется на современных версиях iOS для приложений в фоновом режиме, если специально не убит.
Дополнительные обязанности
Помимо управления жизненным циклом, App Delegate обрабатывает несколько сервисов в масштабе приложения:
- Удаленные и локальные уведомления: Регистрируйте удаленные уведомления через и обрабатывайте входящие уведомления .
- Обработка URL-адресов и передача: Делегат приложения отвечает на пользовательские схемы URL и универсальные ссылки через и управляет деятельностью по передаче данных через .
- Предупреждения памяти: позволяет приложению выпускать кэши, изображения и другие одноразовые ресурсы.
- Бэкграундный приём: Реализуйте , чтобы периодически загружать контент, пока приложение находится в фоновом режиме.
- Watch Connectivity and App Groups: Координация обмена данными между приложением iOS и приложением-компаньоном Watch через App Delegate.
Исторический контекст
До iOS 13 Делегат приложений также отвечал за управление экземпляром одного окна приложения. Разработчики установили контроллер root view внутри . Этот дизайн был простым, но ограничивающим — он не мог поддерживать несколько одновременных окон. Введение сцен в iOS 13 переместило управление окнами на отдельные объекты делегата, оставив Делегата приложений свободным сосредоточиться исключительно на проблемах приложений.
Что такое делегат сцены?
С iOS 13 и iPadOS 13 Apple представила протокол UISceneDelegate для поддержки нескольких окон в приложении. Сцена представляет собой один экземпляр пользовательского интерфейса вашего приложения, обычно поддерживаемый объектом . Каждая сцена имеет свой жизненный цикл и может отображаться на отдельном дисплее или в отдельном пространстве на iPad. Делегат сцены управляет жизненным циклом конкретной сцены, состоянием пользовательского интерфейса и взаимодействиями.
Поддержка Multi-Window
Чтобы использовать сцены, вы должны выбрать настройку вашего приложения с помощью ключа «Манифест сцены приложения». Этот манифест определяет конфигурации сцены, включая имена классов делегатов и роли сеансов. Без этого манифеста iOS рассматривает приложение как одноокно и продолжает использовать устаревшее управление окном делегата приложения.
Методы жизненного цикла основной сцены
Делегат сцены реализует методы, аналогичные Делегату приложения, но с размахом в одну сцену:
- — Называется, когда новая сцена собирается быть добавлена в приложение. Здесь вы настраиваете контроллер корневого просмотра сцены и начальный пользовательский интерфейс. Вы получаете объект , который предоставляет информацию об URL, активности или ярлыке, который вызвал сцену.
- — Сцена становится активной (на переднем плане и в фокусе). Резюме приостанавливает действия, запускает анимацию и обновляет данные.
- — Сцена вот-вот станет неактивной (например, многозадачный жест, переключатель приложений).
- — Сцена перемещается на задний план. Высвободить ресурсы, сохранить данные и запланировать фоновые задачи для этой сцены.
- — Сцена вот-вот станет активной на переднем плане.
- — Называется, когда система удаляет сцену из приложения (например, пользователь закрывает окно на iPad, или приложение перемещается в фоновый режим, и система решает отбросить сцену).
Сценические сессии и роли
Каждая сцена связана с объектом , который сохраняется при запуске. Сеансы могут быть повторно использованы или созданы заново. Сессия содержит свойство , которое указывает, является ли сцена для основного интерфейса приложения () или внешнего дисплея (). Делегат сцены может проверить роль сессии для адаптации ее поведения.
Сцена делегата в SwiftUI
Для приложений SwiftUI Scene Delegate часто автоматически генерируется, когда вы начинаете новый проект, ориентированный на iOS 14+. Тем не менее, вы все еще можете создать пользовательский Scene Delegate, используя обертку свойств в вашей структуре . Сцена SwiftUI косвенно использует , но вы можете переопределить поведение делегата, сообразовываясь с в адаптере.
Основные различия между делегатом приложения и делегатом сцены
Хотя оба делегата управляют жизненным циклом, их сфера и обязанности значительно различаются:
- Сфера: Делегат приложения работает на уровне процесса подачи заявки; на приложение приходится только один. Делегат сцены работает на уровне сцены (или окна); у вас может быть несколько делегатов сцены, работающих одновременно.
- Введение: Делегат приложений существует с iOS 2. Делегат сцены был представлен в iOS 13 для обеспечения поддержки нескольких окон.
- Управление Windows: В унаследованных приложениях App Delegate владеет окном. В приложениях на основе сцены каждый Scene Delegate владеет окном сцены. App Delegate больше не получает доступ к окну напрямую.
- Сохранение состояния: Приложения, использующие сцены, должны осуществлять сохранение и восстановление состояния на уровне сцены (через или ), а не только через Делегата приложения.
- Задачи фона: В целом, фоновые задачи могут быть запущены в масштабах приложения (через App Delegate) или в каждой сцене (через Scene Delegate). Однако некоторые фоновые режимы, такие как фоновый выбор, по-прежнему управляются App Delegate.
Как они работают вместе в современном приложении
В приложении iOS на основе сцены делегат приложения и делегат сцены образуют многоуровневую архитектуру. Делегат приложения инициализирует общую инфраструктуру — журналирование, аналитику, базовую базу данных — и обрабатывает события, которые не принадлежат к конкретной сцене. Когда системе нужно отображать новый контент, она создает сцену и связывает делегат сцены. Делегат сцены затем создает пользовательский интерфейс, подключается к сеансу сцены и управляет взаимодействиями пользователей в этой сцене.
Координация во время запуска
Когда пользователь открывает приложение, система вызывает делегата приложения . После этого система создает сцену и вызывает на делегате сцены. Если приложение вновь открывается через Handoff или ярлык, доставляет соответствующую активность, URL или активность пользователя соответствующему делегату сцены.
Реставрация штата на разных сценах
Восстановление состояния имеет решающее значение для бесшовной многозадачности. Каждая сцена должна кодировать свое состояние с помощью метода делегата сцены . Делегат приложения отвечает за предоставление типов активности через при создании сеанса сцены. Эта координация гарантирует, что вновь открытые сцены восстанавливают свой контент — например, приложение для документов может повторно открыть точный файл, который пользователь редактировал в каждом окне.
Обработка внешних дисплеев
На iPad сцена может быть создана на внешнем мониторе через «AirPlay» или «Sidecar». Проверяя роль , Scene Delegate может настроить свой пользовательский интерфейс в соответствии с разрешением и возможностями внешнего дисплея. App Delegate по-прежнему не знает, на каком дисплее находится сцена, сохраняя обязанности четко разделенными.
Практический пример: настройка приложения для iOS на основе сцены
Давайте пройдемся по шагам, чтобы настроить новое приложение UIKit с делегатами сцены. Предположим, вы начинаете с пустого проекта Xcode с включенной опцией «Use Scene Delegate».
Шаг 1: Инфо.plist Конфигурация
Xcode automatically adds the “Application Scene Manifest” entry. Open the Info.plist and verify it contains a dictionary with:
- Включить несколько окон: Да (если вы хотите разрешить несколько окон; в противном случае НЕТ).
- Конфигурации сцены : множество словарей, каждый из которых определяет роль сцены (например, «Приложение Windows») и имя класса делегата (например, «$ (PRODUCT MODULE NAME.SceneDelegate)».
Для приложения с одним окном вы можете оставить несколько окон отключенными, но вам все равно нужна конфигурация сцены для использования Scene Delegate.
Шаг 2: Внедрить приложение делегат
В , удалите любое свойство окна. Вместо этого, реализуйте только общие методы приложения:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Configure analytics, core data, third-party SDKs
return true
}
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Return a scene configuration to use for the new scene
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
// Called when the user discards a scene (e.g., closing a window)
}
}
Шаг 3: Внедрение сцены делегата
В , управлять окном и жизненный цикл сцены:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let viewController = ViewController()
window.rootViewController = viewController
self.window = window
window.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called when the scene is being removed from the app
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Resume tasks
}
func sceneWillResignActive(_ scene: UIScene) {
// Pause tasks
}
}
Шаг 4: Обработка вариантов подключения сцены
в предоставляет ярлыки, контексты URL и действия пользователя. Например, чтобы открыть конкретный документ, когда пользователь нажимает файл:
if let urlContext = connectionOptions.urlContexts.first {
// Intialize a document viewer with the URL
urlContext.url.startAccessingSecurityScopedResource()
// Load document and set root view controller
}
Это разделение позволяет Делегату приложений наклоняться, и каждый Делегат сцены сосредоточен на своем собственном окне.
Лучшие практики и общие подводные камни
Когда использовать App Delegate vs. Scene Delegate
- Используйте App Delegate для инициализации, которая должна происходить ровно один раз за запуск приложения, например, отчет о сбоях, аутентификация пользователя или миграция в базу данных.
- Используйте Scene Delegate для настройки пользовательского интерфейса, инстанцирования контроллера просмотра и управления состоянием, специфичным для сцены.
- Не делайте , не , чтобы получить доступ к общему , чтобы получить окно; вместо этого, извлеките окно из делегата активной сцены.
Миграция из Legacy Apps
Если у вас есть существующее приложение с одним окном, которое использует App Delegate для управления окнами, вы можете принять сцены, добавив манифест сцены и переместив код, связанный с окном, в новый Scene Delegate.
Память и соображения производительности
Каждая сцена потребляет память и ресурсы. На iPad система может отключать сцены, когда память низкая. Внедрять , чтобы выпускать ресурсы, специфичные для сцены. Избегайте хранения больших кэшей или данных в Делегате сцены; используйте Делегат приложений для кэшей в масштабе приложения, которые могут пережить отключение сцены.
Обращение с делегатами в SwiftUI
В SwiftUI вы можете прикрепить пользовательский Делегат приложения через . Однако для управления сценами SwiftUI автоматически использует конфигурацию сцены по умолчанию. Если вам нужно пользовательское поведение сцены (например, обработка контекстов URL на окно), создайте класс, соответствующий , и назначьте его в манифесте или через модификатор .
Заключение
Делегаты приложений и Делегаты сцены являются дополнительными столпами современной архитектуры приложений iOS. Делегаты приложений обеспечивают единую точку управления для событий уровня приложений, в то время как Делегаты сцены управляют жизненным циклом окна и пользовательским интерфейсом. Понимая их различные обязанности и как они сотрудничают, вы можете создавать приложения, которые изящно поддерживают несколько окон, восстановление состояния и отзывчивый пользовательский опыт на всех устройствах iOS. Для дальнейшего чтения обратитесь к документации Apple UIApplicationDelegate , документации UISceneDelegate и руководству по управлению жизненным циклом вашего приложения .