Live Activity — een dynamische widget op het vergrendelscherm van de iPhone en in Dynamic Island die informatie in realtime weergeeft: leveringsstatus, sportuitslagen, timers en muziekweergave. Het wordt geïmplementeerd via ActivityKit (Swift, iOS 16.1+) samen met WidgetKit. Live Activity wordt lokaal of via pushmeldingen bijgewerkt, ondersteunt meerdere statussen en wordt door het systeem beëindigd na afloop van de gebeurtenis. Meer op ActivityKit Documentation.
Belangrijkste punten
Live Activity — een WidgetKit-extensie die dynamische inhoud weergeeft op het vergrendelscherm van de iPhone en in Dynamic Island. In tegenstelling tot een statische widget die wordt bijgewerkt volgens de systeemtimer, wordt Live Activity gestart door een app en leeft het een beperkte tijd — tot 8 uur voor een actieve Activity en tot 4 uur na voltooiing. De gebruiker ziet actuele gegevens zonder het apparaat te ontgrendelen: de status van een leveringsorder, afstand tot de bestemming in een taxi, wedstrijduitslag of trainingsvoortgang.
ActivityKit — framework voor het werken met Live Activities, geïntroduceerd in iOS 16.1. Het biedt een API voor het aanvragen, bijwerken en beëindigen van een Activity. Een Activity is een object met inhoud en status. De inhoud (ActivityContent) definieert statische gegevens, de status (ActivityState) — dynamische gegevens die in de loop van de tijd veranderen. Het systeem beslist zelf wanneer het een nieuwe status moet renderen — dit bespaart batterij en garandeert vloeiende animaties.
Elke Live Activity wordt uniek geïdentificeerd door een ActivityID en is gekoppeld aan één proces — de app die deze heeft gemaakt. Het systeem kan een Activity beëindigen bij onvoldoende geheugen of een lage batterij. De ontwikkelaar krijgt een melding van gedwongen beëindiging via de ActivityKit-delegate en kan de laatste status opslaan voor herstel.
De architectuur van Live Activity is gebaseerd op twee frameworks: WidgetKit is verantwoordelijk voor het renderen van SwiftUI-weergaven, ActivityKit — voor de levenscyclus van een Activity. De ontwikkelaar maakt een WidgetBundle met ondersteuning voor LiveActivityConfiguration. Elke configuratie definieert het gegevenstype (Attributes en State) en de SwiftUI View die door het systeem wordt gerenderd op het Lock Screen en Dynamic Island. Gegevens worden overgedragen via ActivityAttributes — een struct met let-velden voor inhoud en var-velden voor status.
| Component | Doel | API |
|---|---|---|
| Attributes | Statische gegevens van de hele Activity | let name: String, let icon: String |
| ContentState | Dynamische status, veranderd bij update | var progress: Double, var status: Status |
| Activity | Object voor aanvraag en beheer van Activity | Activity.request(attributes:content:) |
| PushToken | Token voor server push-updates | activity.pushToken publisher |
| ActivityUI | SwiftUI View voor Lock Screen en Dynamic Island | LockScreenView, ExpandedView, CompactView |
De levenscyclus van een Activity omvat drie fasen: actief (systeem toont en werkt bij), definitief (activiteit voltooid maar UI nog 4 uur zichtbaar), verwijderd (systeem verwijdert UI). De app kan een Activity op elk moment beëindigen. Het systeem beëindigt ook gedwongen een Activity — bijvoorbeeld bij een herstart van het apparaat of het verstrijken van de 8-uurslimiet.
import ActivityKit
struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable & Hashable {
var status: DeliveryStatus
var estimatedMinutes: Int
}
var orderNumber: String
var restaurantName: String
}
WidgetBundle registreert Live Activity via de @main-macro: de widget retourneert een lijst met configuraties, waaronder LiveActivityConfiguration. Op basis van deze configuratie weet het systeem welke gegevenstypen te verwachten en hoe de UI in verschillende statussen moet worden gerenderd — compact, minimaal en uitgebreid voor Dynamic Island.
Een Activity maken begint met een verzoek aan ActivityKit. De app roept Activity.request(attributes:content:pushType:) aan met initiële gegevens. Het systeem controleert of Dynamic Island beschikbaar is op het apparaat en retourneert een Activity-object. Het verzoek kan mislukken als de limiet van actieve Activities is overschreden — meestal niet meer dan 5 tegelijk. Na een succesvol verzoek toont het systeem de widget op het Lock Screen en, indien mogelijk, in Dynamic Island.
let attributes = DeliveryAttributes(
orderNumber: "A-1234",
restaurantName: "Pizza House"
)
let initialState = DeliveryAttributes.ContentState(
status: DeliveryStatus.preparing,
estimatedMinutes: 30
)
do {
let activity = try await Activity<DeliveryAttributes>.request(
attributes: attributes,
content: ActivityContent(state: initialState, staleDate: nil),
pushType: .token
)
print("Activity started: \(activity.id)")
} catch {
print("Failed: \(error)")
}
SwiftUI View voor Live Activity gebruikt de structuren LockScreenView, ExpandedView en CompactView van WidgetKit. De View ontvangt context (ActivityViewContext) met de huidige attributen en status. De View wordt automatisch bijgewerkt bij ontvangst van een nieuwe status van het systeem. Live Activity ondersteunt slechts een beperkte set SwiftUI-componenten — Text, Image, HStack, VStack en enkele modifiers.
Elke Live Activity View moet licht en snel zijn — het systeem weigert zware weergaven te renderen. De tijdslimiet voor renderen is 30 ms per frame. Animaties zijn beperkt tot systeemovergangen tussen statussen — aangepaste animaties in Live Activity zijn niet beschikbaar. Het renderen wordt op de achtergrond uitgevoerd door het WidgetKit-proces met prioriteit voor de responsiviteit van het Lock Screen.
Lokale update — de app werkt de status van een Activity bij door activity.update(using:) aan te roepen. De methode ontvangt een nieuwe ContentState en een optionele AlertConfiguration voor het tonen van een melding bij de update. Lokale updates zijn snel — het systeem hertekent de View in de volgende rendercyclus, meestal binnen 1–2 seconden. Voor frequente updates (timer, stopwatch) gebruik je de lokale modus — dit is betrouwbaarder en sneller dan push.
let updatedState = DeliveryAttributes.ContentState(
status: DeliveryStatus.outForDelivery,
estimatedMinutes: 10
)
await activity.update(
ActivityContent<DeliveryAttributes.ContentState>(
state: updatedState,
staleDate: Date().addingTimeInterval(60)
),
alertConfiguration: AlertConfiguration(
title: "Order out for delivery",
body: "Arriving in 10 min"
)
)
Push-updates — de server stuurt een ActivityKit pushmelding met een nieuwe status in JSON-formaat. Hiervoor ontvangt de app een pushToken van de activity.pushToken publisher en geeft deze door aan de server. De server stuurt een POST-verzoek naar APNs met een payload die de nieuwe ContentState bevat. Het systeem ontvangt de push, decodeert de status en werkt Live Activity bij zonder tussenkomst van de app — dit maakt het mogelijk om de Activity bij te werken, zelfs wanneer de app is gesloten.
Push-updates zijn zuiniger dan lokale voor zeldzame updates (leveringsstatus elke 5–10 minuten) — de app hoeft geen netwerkverbinding te onderhouden. Voor frequente updates elke 1–2 seconden gebruik je de lokale methode. De server-payload bevat alleen de wijzigbare velden van ContentState — de statische gegevens van Attributes worden alleen verzonden bij het maken van de Activity.
Dynamic Island — een hardware-softwaregebied op iPhone 14 Pro, 15 Pro en nieuwer dat zich aanpast aan de inhoud van Live Activity. Het systeem toont de Activity automatisch in drie modi: compact (pictogram + korte tekst links van de uitsparing), minimaal (alleen pictogram) en uitgebreid (rechthoek van 300pt met informatie). De ontwikkelaar beheert deze modi niet rechtstreeks — het systeem kiest de modus op basis van prioriteit en beschikbare ruimte.
struct DeliveryLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: DeliveryAttributes.self) { context in
LockScreenView(context: context)
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedContent {
ExpandedView(context: context)
}
} compactLeading: {
CompactLeadingView(context: context)
} compactTrailing: {
CompactTrailingView(context: context)
} minimal: {
MinimalView(context: context)
}
}
}
}
Dynamic Island ondersteunt interactiviteit — de gebruiker tikt op het gebied en komt in de app of opent de uitgebreide weergave. Tikken op de compacte modus schakelt over naar de uitgebreide modus, en vegen naar links verbergt de Activity naar de minimale modus. Knoppen in de uitgebreide modus (pause/cancel) worden afgehandeld via Link uit SwiftUI — het systeem start de app met een deep link URL, de afhandeling gebeurt in UIApplicationDelegate.
Beperkingen van Dynamic Island: breedte van de uitgebreide modus — tot 300pt, compacte tekst — tot 30 tekens. Kleuren en lettertypen komen overeen met het systeemthema — aanpassing is beperkt. Overgangsanimaties tussen modi zijn systeemeigen en kunnen niet worden geconfigureerd. Als meerdere apps actieve Activities hebben, toont Dynamic Island ze met prioriteit op basis van starttijd en inhoudstype.
Veelgestelde vragen
Een gewone WidgetKit-widget toont statische informatie en wordt bijgewerkt volgens de systeemtimer met een minimuminterval van 15–30 minuten. Live Activity toont dynamische gegevens in realtime op het vergrendelscherm en Dynamic Island. Live Activity wordt gestart door een app, leeft tot 8 uur en wordt door het systeem beëindigd na afloop van de gebeurtenis, in tegenstelling tot de widget die permanent bestaat.
Live Activity ondersteunt twee updatemodi: lokaal — de app werkt de status op elk moment bij via de ActivityKit API, en push — de server stuurt een ActivityKit pushmelding die het systeem omzet in een nieuwe widgetstatus. Bij een lage batterij kan het systeem Live Activity bevriezen tot de oplader wordt aangesloten.
Live Activities zijn beschikbaar op iPhones met iOS 16.1 en nieuwer. Op iPhone 14 Pro en nieuwer wordt Live Activity ook weergegeven in Dynamic Island. Op de iPad wordt Live Activity alleen ondersteund op het vergrendelscherm — Dynamic Island bestaat niet op de iPad. Apple Watch ondersteunt Live Activities niet direct, maar kan meldingen over voltooiing weergeven.
Het systeem beperkt het aantal actieve Live Activities — meestal niet meer dan 5 tegelijk voor alle apps. Bij een poging de limiet te overschrijden, retourneert ActivityKit een fout. Elke Live Activity kan meerdere statussen hebben — bijvoorbeeld wachtend, onderweg, geleverd voor een voedselbestelling. Na voltooiing blijft de Activity nog 4 uur in de UI.
Ja, de app moet toestemming vragen voor het verzenden van meldingen — Live Activity gebruikt het systeemkanaal voor meldingen. De gebruiker kan Live Activity voor een specifieke app uitschakelen in de instellingen. Bij de eerste start toont ActivityKit een dialoog met een verzoek om toestemming. Zonder toestemming mislukt het Activity-verzoek met een fout.
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