Каждое собеседование по iOS начинается гладко, пока интервьюер не подкидывает такой вопрос:
Итак, что происходит, когда вы нажимаете на иконку приложения в iPhone?
Вы замолкаете.
Думаете: SpringBoard? UIApplicationMain? SceneDelegate? Внезапно всё, что вы знали о SwiftUI и Combine, кажется бесполезным.
Я видел, как senior iOS-разработчики — те, кто выпустил несколько приложений для продакшена, — замирали на полуслове, когда возникал этот вопрос.
Не потому, что он сложный, а потому, что он затрагивает более низкий уровень нежели тот, к которому мы привыкли.
Это один из тех обманчиво простых вопросов, который проверяет, понимаете ли вы iOS за пределами API.
Итак, в этой статье мы разберём каждый уровень — от касания пальцем до выполнения первой строки Swift — и посмотрим, что на самом деле происходит при запуске iOS-приложения.
1. Всё начинается с касания (SpringBoard)
Когда вы касаетесь иконки приложения, вы не запускаете его напрямую.
Вы обращаетесь к SpringBoard, закрытому системному приложению, которое реализует функции домашнего экрана iPhone и запуск приложений.
SpringBoard делает гораздо больше, чем просто отображает иконки. Он управляет:
- Макетами ваших приложений
- Идентификаторами пакетов
- Бейджами и уведомлениями
- Переходами жизненного цикла приложения (передний план/фоновая работа)
Итак, когда вы касаетесь значка приложения, происходит следующее:
- SpringBoard обнаруживает событие касания
- Определяет, какой пакет приложения соответствует нажатой иконке
- SpringBoard проверяет, запущено ли приложение в фоновом режиме
- Если да, приложение просто выводится на передний план
- Если нет, необходимо запустить новый процесс.
Именно в этот момент операционная система запускает ваше приложение.
2. ОС создаёт процесс для вашего приложения
Когда SpringBoard запрашивает у системы запуск вашего приложения, ядро и launchd демон берут на себя управление.
Эти два процесса отвечают за создание процессов на системном уровне.
Вот последовательность действий вкратце:
launchd— главный процесс, отвечающий за управление всеми остальными процессами в iOS- Он создаёт новую изолированную среду для вашего приложения
- Он настраивает системные ресурсы: файловые дескрипторы, разрешения, права доступа и т.д.
- Он мепит исполняемый двоичный файл вашего приложения (из
.appбандла) в память - Он подготавливает переменные окружения и подключает необходимые системные библиотеки
Представьте, что ОС говорит:
Хорошо, вот ваше пространство, вот ваша память, вот ваш исполняемый файл. Можете запускать.
Ваше приложение уже существует как процесс, но оно ещё не выполнило ни одной строки кода Swift.
3. Динамический компоновщик (dyld) загружает зависимости
Далее на сцену выходит dyld — динамический компоновщик.
Каждое iOS-приложение зависит от набора системных фреймворков, таких как UIKit, Foundation и рантайма Swift.
Задача dyld — загрузить эти данные в память и связать их с исполняемым файлом вашего приложения.
Вот что делает Dyld:
- Загружает основной исполняемый двоичный файл вашего приложения
- Разрешает ссылки на внешние фреймворки (например, UIKit, CoreGraphics, AVFoundation и т.д.).
- Связывает всё воедино в памяти, чтобы среда выполнения знала, где находится каждый символ (функция, класс, константа)
На этом этапе время запуска приложения может варьироваться — чем больше зависимостей, тем больше времени требуется на их связывание.
После завершения работы dyld система наконец-то может запустить функцию main() вашего приложения.
4. UIApplicationMain: рождение вашего приложения
Файл main.swift обычно скрыт в современных проектах Swift, но он там есть. Если вы откроете сгенерированные файлы вашего приложения, вы увидите что-то вроде этого:
import UIKit
UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
nil,
NSStringFromClass(AppDelegate.self)
)
Этот единственный вызов и есть то, где в дело вступает UIKit.
Давайте разберёмся:
- Он создаёт экземпляр синглтона
UIApplication— центральный объект каждого приложения iOS - Он загружает файл Info.plist вашего приложения и считывает конфигурации, такие как поддерживаемые ориентации, основной сториборд, сцены приложения и т.д.
- Он инициализирует ваш класс
AppDelegate(илиSceneDelegateв многоэкранных приложениях) - Он настраивает основной цикл событий — цикл выполнения, который отслеживает пользовательский ввод, таймеры и системные события
На этом этапе ваше приложение работает, но невидимо.
5. SceneDelegate и первое окно
Начиная с iOS 13, Apple представила UIScene и SceneDelegate для обработки многоэкранных сценариев.
После инициализации UIApplication он запускает процесс управления сценой:
- iOS запрашивает у вашего приложения конфигурацию сцены
- Он создаёт
UIWindowScene - Он вызывает
scene(_:willConnectTo:options:)в вашем SceneDelegate - Здесь вы создаёте первое UIWindow приложения и назначаете
rootViewController
Пример:
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = RootViewController()
self.window = window
window.makeKeyAndVisible()
}
Это момент, когда пользовательский интерфейс вашего приложения наконец становится видимым для пользователя.
6. Жизненный цикл приложения в действии
Как только приложение становится видимым, официально начинается жизненный цикл приложения.
Вот упрощённый путь:
- Не запущено → Неактивно: приложение запускается, но пока не реагирует на ввод данных
- Неактивно → Активно: как только оно становится видимым и интерактивным, вы переходите в активное состояние
- Активно → Фоновая работа: происходит, когда пользователь переключает приложения или получает звонок
- Фоновая работа → Приостановка: приложение остаётся в памяти, но останавливает выполнение для экономии энергии
Эти переходы запускают определённые методы делегата:
func applicationDidBecomeActive(_ application: UIApplication) func applicationWillResignActive(_ application: UIApplication) func applicationDidEnterBackground(_ application: UIApplication) func applicationWillEnterForeground(_ application: UIApplication)
Понимание этих хуков — не просто академическая составляющая. Оно позволяет вам обрабатывать фоновые задачи, восстанавливать состояние и плавно запускать приложения.
7. Что насчёт приложений SwiftUI?
Если вы разрабатываете на SwiftUI, вам может показаться, что этот процесс кардинально меняется. Но на самом деле это не так.
Структура @main в SwiftUI просто обёртывает аналогичный процесс — она создаёт экземпляр UIApplication (или NSApplication в macOS) «за кулисами».
Пример:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
На самом деле, это всё ещё вызывает UIApplicationMain().
SwiftUI просто абстрагирует это с помощью декларативного синтаксиса и собственных модификаторов жизненного цикла:
.onAppear.onDisappear@Environment(\.scenePhase)
Таким образом, независимо от того, пишете ли вы на SwiftUI или UIKit, процесс запуска приложения практически идентичен — различаются только API верхнего уровня.
8. Почему интервьюеры задают этот вопрос
Так почему же так много собеседований по iOS включают этот обманчиво простой вопрос?
Потому что речь идёт не о запоминании, а о понимании системы.
Интервьюер не ищет модных словечек вроде «SceneDelegate» или «UIApplicationMain».
Он проверяет:
- Понимаете ли вы, что происходит до запуска вашего кода?
- Можете ли вы объяснить архитектуру iOS на концептуальном уровне?
- Знаете ли вы роли SpringBoard, dyld и среды выполнения?
Хороший ответ — это не длинный ответ, а многоуровневый.
Например, лаконичный ответ на senior уровне может звучать так:
«Когда вы нажимаете на значок приложения, SpringBoard просит систему запустить процесс вашего приложения. Ядро и launchd создают изолированную среду, dyld подключает необходимые фреймворки, а UIApplicationMain запускает жизненный цикл приложения, создавая основной цикл выполнения и настраивая первую сцену».
Вот и всё.
Коротко, структурировано, уверенно — и это демонстрирует глубокое понимание.
9. Бонус: Визуализация всего процесса
Вот ментальная модель, которую вы можете держать в голове:
Нажатие иконки ↓ SpringBoard обнаруживает нажатие ↓ launchd создает процесс ↓ dyld линкует фреймворки ↓ Стартует UIApplicationMain ↓ Инициализируется AppDelegate/SceneDelegate ↓ Загружается RootViewController ↓ Приложение становится активным
Каждый запуск следует этому пути — будь то ваше собственное приложение или Почта.
10. Краткая историческая справка
До iOS 13 SceneDelegate не существовало. Всё управление осуществлялось через AppDelegate, включая создание окон, восстановление состояния и переходы между этапами жизненного цикла.
Пример:
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = RootViewController()
window?.makeKeyAndVisible()
return true
}
SceneDelegate был представлен для поддержки многооконных сред, особенно для многозадачности на iPad.
Но фундаментальный процесс запуска остался неизменным — были разделены только обязанности.
11. Чему можно научиться из этого
Если вы готовитесь к собеседованиям, вот главный вывод:
Глубина важнее ширины.
Вам не нужно запоминать каждый API Apple, но вы должны быть в состоянии ответить на такие вопросы, как:
- Что на самом деле запускает моё приложение?
- Когда мой код запускается в первый раз?
- Какую роль играют SpringBoard или dyld?
- С чего начинается жизненный цикл приложения?
Интервьюеры любят этот вопрос, потому что он различает разработчиков, использующих iOS, и разработчиков, понимающих iOS.
И это настоящее определение senior инженера — человека, который может смотреть дальше кода и объяснять работу систем.
Заключение
В следующий раз, когда кто-то спросит «что происходит, когда вы нажимаете на иконку приложения?» — не паникуйте.
Начните с системного уровня и уверенно проведите спрашивающего через всю последовательность. Покажите, что вы понимаете, как iOS загружает ваше приложение, настраивает его среду и управляет его жизненным циклом.
Потому что чем глубже вы понимаете, тем проще вы можете объяснить.
И на собеседовании — это то, что бросается в глаза.

