← Назад к вопросам

Для чего нужна функция scene в SceneDelegate?

1.6 Junior🔥 182 комментариев
#UIKit и верстка

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Роль функции scene в SceneDelegate

В современной iOS-архитектуре с поддержкой многозадачности и нескольких сцен, функция scene(_:willConnectTo:options:) в SceneDelegate является ключевой точкой входа и настройки отдельной сцены (scene) вашего приложения. Её основное предназначение — инициализация и конфигурация пользовательского интерфейса для новой сцены, которая представляет собой отдельный экземпляр UI вашего приложения, работающий параллельно с другими сценами.

Основные задачи функции scene

1. Создание корневого UIWindow и контроллера представлений

Функция вызывается системой, когда создаётся новая сцена. Здесь происходит:

  • Инициализация UIWindow, связанного с данной UISceneSession
  • Назначение rootViewController (часто UINavigationController, UITabBarController или кастомный контроллер)
  • Активация окна методом makeKeyAndVisible()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, 
           options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    window = UIWindow(windowScene: windowScene)
    let rootVC = MainViewController()
    window?.rootViewController = UINavigationController(rootViewController: rootVC)
    window?.makeKeyAndVisible()
}

2. Обработка контекста запуска сцены

Функция получает connectionOptions, которые содержат:

  • URLs — если приложение было открыто через Universal Links или Custom URL Scheme
  • UserActivities — для продолжения работы с NSUserActivity (Handoff, Spotlight)
  • CloudKitShareMetadata — для работы с общими документами iCloud
  • NotificationResponse — если сцена была открыта через интерактивное уведомление
// Пример обработки URL при запуске
if let urlContext = connectionOptions.urlContexts.first {
    handleIncomingURL(urlContext.url)
}

// Пример обработки UserActivity
if let userActivity = connectionOptions.userActivities.first {
    configureScene(for: userActivity)
}

3. Восстановление состояния сцены

При использовании State Restoration:

  • Восстановление иерархии контроллеров
  • Восстановление данных сессии
  • Настройка интерфейса на основе сохранённого состояния

4. Многозадачность и поддержка нескольких окон

В iPadOS и macOS:

  • Каждая сцена работает независимо
  • Возможность разных конфигураций для разных сцен
  • Раздельное управление жизненным циклом

Ключевые отличия от AppDelegate

Важно понимать разграничение ответственности:

SceneDelegateAppDelegate
Управление одной сценойУправление всем приложением
Конфигурация UIWindowКонфигурация приложения
Обработка жизненного цикла сценыОбработка жизненного цикла приложения
Работа с UserActivities для конкретной сценыРегистрация глобальных обработчиков

Практический пример настройки

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, 
           options connectionOptions: UIScene.ConnectionOptions) {
    
    // 1. Безопасное приведение типа
    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    // 2. Создание и настройка окна
    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene
    
    // 3. Конфигурация зависимости от контекста запуска
    let rootViewController: UIViewController
    
    if let shortcutItem = connectionOptions.shortcutItem {
        // Запуск через Quick Action
        rootViewController = configureForShortcut(shortcutItem)
    } else if let userActivity = connectionOptions.userActivities.first,
              userActivity.activityType == "com.app.detailsView" {
        // Запуск через Handoff/Spotlight
        rootViewController = configureForUserActivity(userActivity)
    } else {
        // Обычный запуск
        rootViewController = MainTabBarController()
    }
    
    // 4. Настройка иерархии навигации
    let navigationController = UINavigationController(rootViewController: rootViewController)
    navigationController.navigationBar.prefersLargeTitles = true
    
    // 5. Установка корневого контроллера
    window?.rootViewController = navigationController
    
    // 6. Восстановление состояния (если нужно)
    if let restorationActivity = session.stateRestorationActivity {
        rootViewController.restoreUserActivityState(restorationActivity)
    }
    
    // 7. Активация окна
    window?.makeKeyAndVisible()
    
    // 8. Дополнительная настройка сцены
    windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
}

Важные нюансы реализации

  1. Всегда проверяйте приведение типа к UIWindowScene
  2. Не создавайте новые UIWindow без привязки к windowScene
  3. Учитывайте различные сценарии запуска через connectionOptions
  4. Поддерживайте State Restoration для лучшего UX
  5. Тестируйте различные конфигурации сцен в многозадачном режиме

Функция scene(_:willConnectTo:options:) — это мост между системной инфраструктурой сцен и логикой вашего приложения, обеспечивающий гибкость, многозадачность и надёжное восстановление состояния для современных iOS-приложений.