Active — de actieve status van de levenscyclus van een iOS-app, waarin deze op de voorgrond staat, aanraakgebeurtenissen ontvangt en met de gebruiker interageert. We onderzoeken hoe de status Active werkt, welke methoden van de UIApplicationDelegate-delegate ervoor verantwoordelijk zijn en hoe je correct omgaat met overgangen tussen Active en Inactive in Swift.
Belangrijkste
Active — een status van de levenscyclus van een mobiele app, waarin deze op de voorgrond staat, wordt weergegeven op het scherm van het apparaat en actief met de gebruiker interageert. In deze status ontvangt de app alle aanraakgebeurtenissen, toetsaanslagen, gegevens van de accelerometer en gyroscoop, en heeft volledige toegang tot de grafische processor voor het renderen van de interface.
Op iOS maakt de status Active deel uit van het vijftoestandenmodel van de levenscyclus: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running. Op Android is het equivalent de status van Activity na het aanroepen van onResume, wanneer Activity bovenaan de stapel staat en gebruikersinvoer ontvangt. Active is de enige status waarin de UI volledig interactief is en reageert op gebaren, scrollen, klikken en animaties.
Het systeem geeft de app in Active maximale prioriteit voor processor en RAM. Dit betekent dat het systeem zo'n app niet zal beëindigen bij gebrek aan bronnen — eerst worden achtergrond- en onderbroken processen verwijderd. De app moet echter efficiënt met bronnen omgaan om de batterij niet leeg te trekken en CPU-throttling te voorkomen.
Voor de gebruiker is Active de normale werkstatus met de app. De gebruiker ziet de interface, kan knoppen indrukken, formulieren invullen, door de feed scrollen. Elke onderbreking van deze status (oproep, melding, omhoog vegen voor Control Center) brengt de app naar Inactive, waarna deze kan terugkeren naar Active of naar Background kan gaan.
iOS gebruikt UIApplicationMain voor statusbeheer. Bij de overgang naar Active roept het systeem applicationDidBecomeActive aan. Voor SwiftUI is het vergelijkbare mechanisme het observeren van scenePhase via Environment. Android gebruikt onResume als indicator van Activity-activiteit op de voorgrond. Beide benaderingen garanderen dat de app een melding krijgt over de statuswijziging en zijn gedrag kan aanpassen.
| Platform | Methode/gebeurtenis | Swift (UIKit) | SwiftUI | Android (Kotlin) |
|---|---|---|---|---|
| iOS | Overgang naar Active | applicationDidBecomeActive | scenePhase == .active | — |
| iOS | Verlaten van Active | applicationWillResignActive | scenePhase == .inactive | — |
| Android | Overgang naar Active | — | — | onResume() |
| Android | Verlaten van Active | — | — | onPause() |
In iOS wordt de status Active verwerkt via UIApplicationDelegate. De belangrijkste methode — applicationDidBecomeActive(_:). Deze wordt aangeroepen bij de eerste start van de app en bij terugkeer uit Inactive. Deze methode is de ideale plaats voor het hervatten van taken die zijn onderbroken bij het verlaten naar Inactive: starten van animaties, hervatten van timers, herstarten van sensoren, controleren van gegevensupdates op de server.
Sinds iOS 13 heeft Apple UISceneDelegate geïntroduceerd voor ondersteuning van meerdere vensters op iPad. In dit geval wordt applicationDidBecomeActive vervangen door sceneDidBecomeActive voor elke scène. Apps die slechts één scherm ondersteunen, kunnen UIApplicationDelegate blijven gebruiken. Beide benaderingen worden aangeroepen op het moment dat de app of scène actief wordt.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// App is actief geworden — taken hervatten
func applicationDidBecomeActive(_ application: UIApplication) {
resumeAnimations()
restartTimers()
refreshDataIfNeeded()
startObservingSensors()
}
// App verliest activiteit — onderbreken
func applicationWillResignActive(_ application: UIApplication) {
pauseAnimations()
stopTimers()
saveDraftData()
}
private func resumeAnimations() {
UIView.animate(withDuration: 0.3) {
// Hervatten van UI-animaties
}
}
private func refreshDataIfNeeded() {
let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
if Date().timeIntervalSince(lastRefresh) > 300 {
fetchDataFromServer()
}
}
}De code toont correcte verwerking van Active in UIKit. applicationDidBecomeActive hervat animaties, timers en controleert of gegevensupdate nodig is. applicationWillResignActive onderbreekt alles dat bronnen kan verbruiken en slaat concepten op. Zo'n paar methoden garandeert dat de app correct reageert op statuswijzigingen.
In SwiftUI is er geen AppDelegate — statusbeheer gebeurt via Environment<ScenePhase>. De waarde .active wordt ingesteld wanneer de scène op de voorgrond staat en interactief is. SwiftUI herstart automatisch animaties en updates bij terugkeer naar Active. De ontwikkelaar hoeft zich alleen te abonneren op onChange om neveneffecten uit te voeren.
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("Scène is actief geworden")
resumeWork()
case .inactive:
print("Scène is inactief geworden")
pauseWork()
case .background:
print("Scène is naar de achtergrond gegaan")
saveState()
@unknown default:
break
}
}
}
private func resumeWork() {
// Hervatten van netwerkverzoeken, animaties
}
private func pauseWork() {
// Onderbreken van tijdgevoelige taken
}
private func saveState() {
// Opslaan van app-status
}
}In SwiftUI is scenePhase de enige bron van waarheid over de status van de app. onChange maakt het mogelijk acties uit te voeren bij elke overgang. Het is belangrijk om te onthouden dat scenePhase alleen beschikbaar is op iOS 14+ en in SwiftUI Lifecycle. Voor UIKit-apps met SwiftUI-schermen gebruik je de aanpak met UIApplicationDelegate.
Active kan op verschillende manieren worden bereikt. De eerste en voor de hand liggende — koude start: de gebruiker klikt op het pictogram, de app gaat van Not Running via Inactive naar Active. De tweede — terugkeer uit de achtergrond: de gebruiker schakelt terug naar de app via App Switcher, de app gaat via Inactive en wordt Active. De derde — terugkeer van een tijdelijke onderbreking: de gebruiker beëindigt een oproep, sluit Control Center of reageert op een melding — de app keert terug van Inactive naar Active.
Not Running → Inactive → Active — koude start. Background → Inactive → Active — terugkeer uit de achtergrond. Inactive → Active — terugkeer van tijdelijke onderbreking. In elk geval wordt applicationDidBecomeActive aangeroepen, maar de context kan verschillen. Bij koude start wordt vóór Active didFinishLaunchingWithOptions aangeroepen, bij terugkeer uit de achtergrond — willEnterForeground. De ontwikkelaar kan deze verschillen gebruiken om een strategie voor statusherstel te kiezen.
| Scenario | Overgangspad | iOS-callbacks | Android-callbacks |
|---|---|---|---|
| Koude start | Not Running → Active | didFinishLaunching → didBecomeActive | onCreate → onStart → onResume |
| Terugkeer uit achtergrond | Background → Active | willEnterForeground → didBecomeActive | onRestart → onStart → onResume |
| Terugkeer uit Suspended | Suspended → Active | willEnterForeground → didBecomeActive | onRestart → onStart → onResume |
| Na onderbreking | Inactive → Active | didBecomeActive | onResume |
Belangrijke opmerking: bij terugkeer uit Suspended roept iOS didFinishLaunchingWithOptions niet aan, omdat de app al in het geheugen was geladen. Dit betekent dat de initialisatiecode die in deze methode is geplaatst, niet opnieuw wordt uitgevoerd. Ontwikkelaars vergeten dit vaak en verplaatsen kritieke logica naar applicationWillEnterForeground of applicationDidBecomeActive voor beide scenario's.
In Android is het equivalent van Active de status van Activity na het aanroepen van onResume(). Activity wordt als actief beschouwd wanneer het op de voorgrond staat en gebruikersinvoer ontvangt. Deze status komt overeen met de top van de Activity-stapel. Als een andere Activity erboven verschijnt (zelfs gedeeltelijk), gaat de huidige Activity naar de status onPause — het equivalent van iOS Inactive.
Het belangrijkste verschil van Android — meerdere Activities kunnen tegelijkertijd actief zijn in multi-window-modus (split screen, freeform). In dit geval wordt de Activity waarmee de gebruiker interageert als actief beschouwd en de aangrenzende als onderbroken (onPause). iOS ondersteunt geen multi-window op iPhone, alleen op iPad via UIScene.
class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
// App is actief geworden — taken hervatten
resumeCameraPreview()
startLocationUpdates()
activateSensors()
}
override fun onPause() {
super.onPause()
// App verliest activiteit — bronnen vrijgeven
releaseCamera()
stopLocationUpdates()
deactivateSensors()
}
private fun resumeCameraPreview() {
// Starten van cameravoorbeeld (vereist toestemming)
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()
)
}
}De code toont verwerking van Active in Android via onResume/onPause. onResume hervat het werk met de camera, geolocatie en sensoren — bronnen die alleen actief moeten zijn wanneer de app zichtbaar is voor de gebruiker. onPause geeft deze bronnen vrij om de batterij niet te verbruiken. CameraX lifecycle-aware API stopt automatisch de voorbeeldweergave bij onPause.
Eerste regel — voer geen zware bewerkingen uit in applicationDidBecomeActive of onResume. Gegevens laden, JSON parsen, werken met de database — dit alles moet asynchroon zijn en de hoofdthread niet blokkeren. Gebruik GCD (DispatchQueue) in iOS en Coroutines in Kotlin voor achtergrondtaken. De hoofdthread moet alleen de UI bijwerken en asynchrone bewerkingen starten.
Tweede regel — synchroniseer de status bij elke terugkeer naar Active. De gebruiker kan instellingen hebben gewijzigd in de systeemapp, een pushmelding hebben ontvangen of gegevens hebben bijgewerkt in een andere app. Controleer de actualiteit van de cache bij overgang naar Active — mogelijk zijn gegevens verouderd tijdens de afwezigheid van de gebruiker.
Derde regel — vertrouw niet op Active als enige status. De app kan Active overslaan en rechtstreeks van Not Running naar Background gaan (indien gestart op de achtergrond). Op iOS gebeurt dit bij start via een pushmelding met de optie content-available. Op Android — bij start via BroadcastReceiver. Controleer altijd de huidige status voordat je UI-bewerkingen uitvoert.
Vierde regel — gebruik Activity Result API op Android in plaats van onActivityResult. Hiermee kun je het resultaat van een camera-, galerij- of machtigingsoproep direct in Active-status verwerken zonder gegevensverlies bij het opnieuw aanmaken van Activity. Gebruik voor iOS async/await met UIApplication.shared.open voor systeemdialoogvensters.
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 {
// Uitvoering uitstellen tot terugkeer naar Active
NotificationCenter.default.addObserver(
forName: .appDidBecomeActive,
object: nil,
queue: .main
) { _ in
block()
}
}
}
}
extension Notification.Name {
static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}De code toont een statusbeheerder voor Active die andere componenten van de app in staat stelt de huidige actieve status te controleren. performWhenActive voert het blok onmiddellijk uit (als de app actief is) of stelt de uitvoering uit tot terugkeer naar Active. Dit is handig voor services die een actie moeten uitvoeren nadat de gebruiker terugkeert naar de app.
Veelgestelde vragen
De methode wordt elke keer aangeroepen wanneer de app naar de actieve status gaat: bij de eerste start, bij terugkeer uit de achtergrond, na het sluiten van Control Center of Notification Center, na het beëindigen van een oproep. In een normale sessie kan dit 5–10 keer worden aangeroepen, afhankelijk van de acties van de gebruiker. Plaats geen eenmalige initialisatie in deze methode.
Visible — een informele term die betekent dat de app zichtbaar is op het scherm, maar mogelijk geen gebeurtenissen ontvangt (bijvoorbeeld gedeeltelijk bedekt door een ander venster op iPad). Active — de officiële status waarin de app zowel zichtbaar als interactief is. Op iPhone is een Visible-app altijd Active, op iPad is de situatie Visible + Inactive mogelijk.
willEnterForeground wordt aangeroepen bij terugkeer uit de achtergrond, maar de app is nog niet actief — deze bevindt zich in Inactive. didBecomeActive wordt aangeroepen nadat de app volledig interactief is geworden. Als je een actie wilt uitvoeren voordat de gebruiker de interface ziet — gebruik willEnterForeground. Als na weergave — didBecomeActive.
Nee. Active veronderstelt dat de app op de voorgrond staat en wordt weergegeven op het scherm. Zonder zichtbare UI kan de app in Background of Suspended zijn. Uitzondering — iPad multi-window, waarbij één venster actief kan zijn en de andere niet, maar beide zichtbaar zijn. VoiceOver en dictafoon veranderen deze regel niet.
Druk op de iOS-simulator op Cmd+Shift+H om naar het beginscherm te gaan (de app gaat naar Background), klik vervolgens opnieuw op het app-pictogram. Gebruik Cmd+L voor het vergrendelen van het scherm (willResignActive) en ontgrendelen (didBecomeActive). Roep voor het testen van Inactive Control Center (Cmd+Shift+; voor macOS-toetsenbord) of Notification Center aan.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook