← Назад к вопросам
Как получаем уведомления о смене состояния с active на inactive?
1.3 Junior🔥 251 комментариев
#UIKit и верстка
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Мониторинг изменения состояния приложения с active на inactive
Для отслеживания изменения состояния приложения с active на inactive в iOS существуют несколько подходов, которые можно разделить на два основных типа: через уведомления NotificationCenter и через методы жизненного цикла AppDelegate/SceneDelegate.
Основные подходы
1. Через NotificationCenter (универсальный способ)
Система генерирует уведомления при изменении состояния приложения, которые можно наблюдать из любой части кода:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Наблюдение за переходом в неактивное состояние
NotificationCenter.default.addObserver(
self,
selector: #selector(appWillResignActive),
name: UIApplication.willResignActiveNotification,
object: nil
)
// Наблюдение за возвратом в активное состояние
NotificationCenter.default.addObserver(
self,
selector: #selector(appDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil
)
}
@objc func appWillResignActive(_ notification: Notification) {
// Вызывается при переходе из active в inactive
// Например: при входящем звонке, переходе в multitask view, открытии Control Center
print("Приложение переходит в состояние inactive")
saveCurrentState()
pauseGameIfNeeded()
}
@objc func appDidBecomeActive(_ notification: Notification) {
// Вызывается при возврате в активное состояние
print("Приложение снова активно")
resumeGameIfNeeded()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
2. Через AppDelegate (для UIKit без сцен)
В старом подходе с использованием только AppDelegate:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillResignActive(_ application: UIApplication) {
// Вызывается при переходе из active в inactive
// Происходит при прерываниях (звонок, SMS) или при выходе пользователя из приложения
print("applicationWillResignActive вызван")
// Обычные действия:
// - Приостановка таймеров
// - Пауза игр или видео
// - Сохранение состояния UI
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Вызывается при возврате в активное состояние
print("applicationDidBecomeActive вызван")
// Возобновление прерванных задач
}
}
3. Через SceneDelegate (для приложений с поддержкой сцен)
Для приложений, использующих многозадачность и несколько окон:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func sceneWillResignActive(_ scene: UIScene) {
// Вызывается при переходе сцены из active в inactive
// Важно: может вызываться для отдельных сцен в многозадачном режиме
print("Сцена переходит в состояние inactive")
// Сохраняем данные, специфичные для этой сцены
// Приостанавливаем тяжелые операции
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Вызывается при активации сцены
print("Сцена стала активной")
// Восстанавливаем состояние для конкретной сцены
}
}
Ключевые различия и нюансы
Разница между состояниями:
- Active → Inactive: временное состояние, когда приложение все еще работает на переднем плане, но не получает события (например, во время входящего звонка)
- Inactive → Background: приложение полностью уходит с переднего плана
Важные моменты при обработке:
- Скорость выполнения: Методы перехода в inactive должны выполняться быстро (примерно 5 секунд), иначе система может завершить приложение
- Освобождение ресурсов: Рекомендуется освобождать ресурсы, которые не нужны в неактивном состоянии
- Сохранение состояния: Критически важные данные пользователя должны сохраняться
- Приостановка операций: Сетевые запросы, таймеры, анимации должны быть приостановлены
Практический пример комбинированного подхода
class StateManager {
static let shared = StateManager()
private init() {}
private var isAppActive = true
func setupObservers() {
// Для iOS 13+ с поддержкой сцен
if #available(iOS 13.0, *) {
NotificationCenter.default.addObserver(
self,
selector: #selector(handleSceneWillResignActive),
name: UIScene.willDeactivateNotification,
object: nil
)
} else {
// Для более старых версий iOS
NotificationCenter.default.addObserver(
self,
selector: #selector(handleAppWillResignActive),
name: UIApplication.willResignActiveNotification,
object: nil
)
}
}
@objc private func handleSceneWillResignActive() {
print("Сцена деактивируется")
handleTransitionToInactive()
}
@objc private func handleAppWillResignActive() {
print("Приложение деактивируется")
handleTransitionToInactive()
}
private func handleTransitionToInactive() {
isAppActive = false
// 1. Сохраняем пользовательские данные
UserDefaults.standard.synchronize()
// 2. Приостанавливаем воспроизведение медиа
AudioManager.shared.pause()
// 3. Останавливаем таймеры
TimerManager.shared.suspendAllTimers()
// 4. Сохраняем состояние UI
saveUIState()
// 5. Отправляем аналитику
Analytics.track(event: .appWentToInactive)
}
}
Рекомендации по использованию
- Используйте
NotificationCenterдля компонентов, которые должны реагировать на изменение состояния из любого места приложения - Используйте
AppDelegate/SceneDelegateдля глобальных действий, затрагивающих все приложение - Всегда удаляйте наблюдателей в
deinitили при уничтожении объекта - Тестируйте различные сценарии: входящие звонки, уведомления, переход в многозадачность
- Учитывайте многозадачность: в iOS 13+ разные сцены могут находиться в разных состояниях
Выбор конкретного подхода зависит от архитектуры приложения, целевой версии iOS и конкретных требований к обработке изменения состояния.