Active: що таке стан Active в життєвому циклі iOS

Автор: IT Sectr Опубліковано: 2026-03-03 Час читання: 10 хв

Active — the active state of the iOS application lifecycle, in which it is in the foreground, receives touch events and interacts with the user. Let’s figure out how the Active state works, which UIApplicationDelegate methods are responsible for it, and how to correctly handle transitions between Active and Inactive in Swift.

Key Takeaways

  • Active — the application is in the foreground, UIResponder receives touch events, the application is fully interactive
  • applicationDidBecomeActive — the main method signaling the transition to Active on iOS
  • ScenePhase.active — the SwiftUI equivalent, tracked via Environment values
  • Returning from Inactive — after a call, notification, or Control Center the application becomes Active again
  • Resources — in Active the application has the highest priority for memory and CPU

Active: what is this state

Active — a state of the mobile application lifecycle in which it is in the foreground, displayed on the device screen, and actively interacts with the user. In this state, the application receives all touch events, key presses, accelerometer and gyroscope data, and has full access to the graphics processor for rendering the interface.

On iOS, the Active state is part of the five-state lifecycle model: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running. On Android, the equivalent is the Activity state after onResume is called, when the Activity is at the top of the stack and accepts user input. Active is the only state in which the UI is fully interactive and responds to gestures, scrolling, taps, and animations.

The system gives an Active application the highest priority for CPU and RAM. This means the system will not terminate such an application when resources are low — background and suspended processes will be unloaded first. However, the application should use resources efficiently to avoid draining the battery and causing CPU throttling.

For the user, Active is the normal state of working with an application. The user sees the interface, can press buttons, fill out forms, and scroll through feeds. Any interruption of this state (a call, notification, swipe up for Control Center) moves the application to Inactive, after which it can return to Active or go to Background.

How the system determines that the application is Active

iOS uses UIApplicationMain to manage state. When transitioning to Active, the system calls applicationDidBecomeActive. For SwiftUI, the equivalent mechanism is observing scenePhase via Environment. Android uses onResume as an indicator of Activity being in the foreground. Both approaches guarantee that the application receives a state change notification and can adapt its behavior.

PlatformMethod/EventSwift (UIKit)SwiftUIAndroid (Kotlin)
iOSTransition to ActiveapplicationDidBecomeActivescenePhase == .active
iOSLeaving ActiveapplicationWillResignActivescenePhase == .inactive
AndroidTransition to ActiveonResume()
AndroidLeaving ActiveonPause()

Active in iOS: Swift, UIKit and SwiftUI

In iOS, the Active state is handled via UIApplicationDelegate. The main method is applicationDidBecomeActive(_:). It is called on the first launch of the application and when returning from Inactive. This method is the ideal place to resume tasks that were paused when entering Inactive: starting animations, resuming timers, restarting sensors, checking for data updates on the server.

UIKit: AppDelegate and SceneDelegate

With iOS 13, Apple introduced UISceneDelegate to support multiple windows on iPad. In this case, applicationDidBecomeActive is replaced by sceneDidBecomeActive for each individual scene. Applications that support only a single screen can continue using UIApplicationDelegate. Both approaches are called when the application or scene becomes active.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Додаток став активним — поновлюємо завдання
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeAnimations()
        restartTimers()
        refreshDataIfNeeded()
        startObservingSensors()
    }

    // Додаток втрачає активність — призупиняємо
    func applicationWillResignActive(_ application: UIApplication) {
        pauseAnimations()
        stopTimers()
        saveDraftData()
    }

    private func resumeAnimations() {
        UIView.animate(withDuration: 0.3) {
            // Поновлення UI-анімацій
        }
    }

    private func refreshDataIfNeeded() {
        let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
        if Date().timeIntervalSince(lastRefresh) > 300 {
            fetchDataFromServer()
        }
    }
}

The code shows correct Active handling in UIKit. applicationDidBecomeActive resumes animations, timers, and checks if data updates are required. applicationWillResignActive pauses everything that could consume resources and saves drafts. Such a pair of methods ensures that the application correctly responds to state changes.

SwiftUI: scenePhase

SwiftUI has no AppDelegate — state management happens via Environment<ScenePhase>. The .active value is set when the scene is in the foreground and interactive. SwiftUI automatically restarts animations and updates when returning to Active. The developer only needs to subscribe to onChange to perform side effects.

swift
import SwiftUI

@main
struct ActiveDemoApp: App {
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { oldPhase, newPhase in
            switch newPhase {
            case .active:
                print("Сцена стала активною")
                resumeWork()
            case .inactive:
                print("Сцена стала неактивною")
                pauseWork()
            case .background:
                print("Сцена пішла в фон")
                saveState()
            @unknown default:
                break
            }
        }
    }

    private func resumeWork() {
        // Поновлення мережевих запитів, анімацій
    }

    private func pauseWork() {
        // Призупинення чутливих до часу завдань
    }

    private func saveState() {
        // Збереження стану додатка
    }
}

In SwiftUI, scenePhase is the single source of truth about the application state. onChange allows performing actions on each transition. It is important to remember that scenePhase is only available on iOS 14+ and in the SwiftUI Lifecycle. For UIKit applications with SwiftUI screens, use the UIApplicationDelegate approach.

Transitions to the Active state

Active can be reached through several paths. The first and most obvious is a cold start: the user taps the icon, the application goes from Not Running through Inactive to Active. The second is returning from the background: the user switches back to the application via App Switcher, the application passes through Inactive and becomes Active. The third is returning from a temporary interruption: the user ends a call, closes Control Center, or responds to a notification — the application returns from Inactive to Active.

Chain of transitions to Active

Not Running → Inactive → Active — cold start. Background → Inactive → Active — return from background. Inactive → Active — return from a temporary interruption. In each case, applicationDidBecomeActive is called, but the context may differ. On a cold start, didFinishLaunchingWithOptions is called before Active; when returning from the background, willEnterForeground is called. The developer can use these differences to choose a state restoration strategy.

ScenarioTransition pathiOS callbacksAndroid callbacks
Cold startNot Running → ActivedidFinishLaunching → didBecomeActiveonCreate → onStart → onResume
Return from backgroundBackground → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Return from SuspendedSuspended → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
After interruptionInactive → ActivedidBecomeActiveonResume

Important note: when returning from Suspended, iOS does not call didFinishLaunchingWithOptions because the application was already loaded into memory. This means that initialization code placed in this method is not re-executed. Developers often forget this and move critical logic to applicationWillEnterForeground or applicationDidBecomeActive for both scenarios.

Active in Android: Activity lifecycle

In Android, the equivalent of Active is the Activity state after onResume() is called. An Activity is considered active when it is in the foreground and accepts user input. This state corresponds to the top of the Activity stack. If another Activity appears on top (even partially), the current Activity transitions to the onPause state — the equivalent of iOS Inactive.

A key difference in Android is that multiple Activities can be active simultaneously in multi-window mode (split screen, freeform). In this case, the Activity the user is interacting with is considered active, while the neighboring one is paused (onPause). iOS does not support multi-window on iPhone, only on iPad via UIScene.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        // Додаток став активним — поновлюємо завдання
        resumeCameraPreview()
        startLocationUpdates()
        activateSensors()
    }

    override fun onPause() {
        super.onPause()
        // Додаток втрачає активність — звільняємо ресурси
        releaseCamera()
        stopLocationUpdates()
        deactivateSensors()
    }

    private fun resumeCameraPreview() {
        // Запуск попереднього перегляду камери (потрібує дозвіл)
        cameraProvider?.unbindAll()
        cameraProvider?.bindToLifecycle(
            this,
            cameraSelector,
            preview,
            imageAnalyzer
        )
    }

    private fun startLocationUpdates() {
        val locationRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY, 5000
        ).build()
        locationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }
}

The code shows Active handling in Android via onResume/onPause. onResume resumes camera, geolocation, and sensor work — resources that should only be active when the application is visible to the user. onPause releases these resources to avoid draining the battery. The CameraX lifecycle-aware API automatically pauses the preview on onPause.

Best practices for handling Active

First rule — do not perform heavy operations in applicationDidBecomeActive or onResume. Data loading, JSON parsing, database work — all of this should be asynchronous and not block the main thread. Use GCD (DispatchQueue) on iOS and Coroutines in Kotlin for background tasks. The main thread should only update the UI and launch asynchronous operations.

Second rule — synchronize state on every return to Active. The user might have changed settings in a system application, received a push notification, or updated data in another app. Check cache relevance when transitioning to Active — data might have become stale while the user was away.

Third rule — do not rely on Active as the only state. The application can skip Active and go directly from Not Running to Background (if launched in background mode). On iOS, this happens when launched via a push notification with the content-available option. On Android, when launched via BroadcastReceiver. Always check the current state before performing UI operations.

Fourth rule — use the Activity Result API on Android instead of onActivityResult. This allows handling the result of camera, gallery, or permission calls directly in the Active state without data loss on Activity recreation. For iOS, use async/await with UIApplication.shared.open for system dialogs.

swift
import UIKit

final class ActiveStateManager {
    static let shared = ActiveStateManager()
    private var isActive = false

    func setActive(_ active: Bool) {
        isActive = active
        if active {
            NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
        }
    }

    func performWhenActive(_ block: @escaping () -> Void) {
        if isActive {
            block()
        } else {
            // Відкласти виконання до повернення в Active
            NotificationCenter.default.addObserver(
                forName: .appDidBecomeActive,
                object: nil,
                queue: .main
            ) { _ in
                block()
            }
        }
    }
}

extension Notification.Name {
    static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}

The code shows an Active state manager that allows other application components to check the current active state. performWhenActive either executes the block immediately if the application is active, or defers execution until returning to Active. This is useful for services that need to perform an action after the user returns to the application.

Frequently Asked Questions

How often is applicationDidBecomeActive called?

The method is called every time the application transitions to the active state: on first launch, when returning from the background, after closing Control Center or Notification Center, after ending a call. In a normal session it can be called 5–10 times depending on user actions. Do not place one-time initialization in this method.

What is the difference between Active and Visible on iOS?

Visible is an unofficial term meaning the application is visible on the screen but may not receive events (for example, partially covered by another window on iPad). Active is the official state in which the application is both visible and interactive. On iPhone, a Visible application is always Active; on iPad, a Visible + Inactive situation is possible.

What is didBecomeActive vs willEnterForeground?

willEnterForeground is called when returning from the background, but the application is not yet active — it is in Inactive. didBecomeActive is called after the application becomes fully interactive. If you need to perform an action before the user sees the interface — use willEnterForeground. If after displaying — use didBecomeActive.

Can an application be Active without a visible UI?

No. Active implies that the application is in the foreground and displayed on the screen. Without a visible UI, the application can be in Background or Suspended. The exception is iPad multi-window, where one window can be active and another not, but both are visible. VoiceOver and voice recorder do not change this rule.

How to test the transition to Active on the simulator?

On the iOS simulator, press Cmd+Shift+H to go to the Home Screen (the application goes to Background), then tap the application icon again. Use Cmd+L to lock the screen (willResignActive) and unlock (didBecomeActive). To test Inactive, open Control Center (Cmd+Shift+; for macOS keyboard) or Notification Center.

Summary

  • Active — the application state in the foreground with full access to user input and maximum resource priority
  • iOS UIKit — applicationDidBecomeActive for resuming animations, timers and sensors
  • SwiftUI — scenePhase .active via Environment, onChange for side effects
  • Android — onResume/onPause as the Active/Inactive equivalent, with multi-window support
  • Transitions — Active is reached from Not Running (cold start), Background and Inactive
  • Resources — heavy operations in didBecomeActive must be asynchronous, not block the main thread
  • Synchronization — checking cache and data relevance on every return to Active

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також