dynamische Sperrbildschirm-Updates umsetzen
Live Activities zeigen mit ActivityKit fortlaufende Statusinformationen wie einen Lieferstatus direkt auf dem Sperrbildschirm und in der Dynamic Island. Dieser Artikel zeigt Architektur, React-Native-Anbindung und die harten Grenzen der Update-Frequenz.
Inhaltsverzeichnis
- 1. Was Live Activities leisten und warum ActivityKit dahintersteckt
- 2. Architektur: WidgetKit-Extension als technische Voraussetzung
- 3. Integration in eine React-Native-App
- 4. Lokale Updates versus Push-Updates über ActivityKit
- 5. Praxisbeispiel: Live-Lieferstatus nach einer Bestellung
- 6. Zweites Beispiel: Ein Live-Ticker mit hoher Update-Frequenz
- 7. Update-Frequenz und Laufzeit-Grenzen im Detail
- 8. Dynamic-Island-Präsentation: Kompakt, minimal, erweitert
- 9. Einschränkungen und Testing
- 10. Zusammenfassung
- 11. FAQ
1. Was Live Activities leisten und warum ActivityKit dahintersteckt
Live Activities sind ein mit iOS 16.1 eingeführtes System-Feature, mit dem Apps zeitlich begrenzte, sich dynamisch aktualisierende Informationen direkt auf dem Sperrbildschirm und, auf entsprechender Hardware, in der Dynamic Island anzeigen können, ohne dass der Nutzer die App aktiv öffnen muss. Technisch basiert das Feature auf dem ActivityKit-Framework, das eine laufende Aktivität als typisiertes Datenobjekt modelliert, dessen Inhalt sich über die Laufzeit hinweg mehrfach aktualisieren lässt, während Start- und Endzeitpunkt vom System verwaltet werden.
Der entscheidende Unterschied zu klassischen Push-Benachrichtigungen liegt in der Persistenz und Interaktivität: Eine Live Activity bleibt sichtbar verankert, bis sie explizit beendet wird oder ihre maximale Laufzeit erreicht, statt wie eine Notification nach dem Antippen oder Wegwischen zu verschwinden. Für Anwendungsfälle mit fortlaufendem Status, etwa eine Lieferverfolgung oder ein Live-Spielstand, ist das strukturell die passendere Darstellungsform, weil der Nutzer den aktuellen Stand jederzeit auf einen Blick sieht, ohne die App wechseln zu müssen.
2. Architektur: WidgetKit-Extension als technische Voraussetzung
Live Activities lassen sich nicht direkt aus der Haupt-App heraus rendern, sondern erfordern zwingend ein separates Widget-Extension-Target im Xcode-Projekt, das sowohl WidgetKit als auch ActivityKit importiert. In diesem Extension-Target definiert man eine ActivityAttributes-Struktur, die zwischen statischen Daten, etwa der Bestellnummer, und einem dynamischen ContentState, etwa dem aktuellen Lieferstatus, unterscheidet. Nur der ContentState-Teil lässt sich während der Laufzeit einer Aktivität aktualisieren, die statischen Attribute stehen von Beginn an fest.
Die eigentliche visuelle Darstellung wird über SwiftUI-Views innerhalb der Widget-Extension beschrieben, getrennt für den Sperrbildschirm und, sofern die Aktivität auch dort erscheinen soll, für die drei Dynamic-Island-Zustände: kompakt, minimal und erweitert. Diese Trennung bedeutet, dass für ein einziges fachliches Feature effektiv vier verschiedene SwiftUI-Layouts gepflegt werden müssen, was den Implementierungsaufwand gegenüber einer einfachen In-App-Anzeige spürbar erhöht.
// Shared/DeliveryActivityAttributes.swift
import ActivityKit
struct DeliveryActivityAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var status: String
var estimatedMinutes: Int
var isStale: Bool
}
var orderNumber: String
}
3. Integration in eine React-Native-App
Weil Live Activities ein rein natives iOS-Feature sind, existiert keine offizielle React-Native-API dafür, und eine funktionierende Integration verlangt zwingend eigenen nativen Swift-Code oder eine Community-Bibliothek wie react-native-live-activity, die genau diese Bridge bereits kapselt. In beiden Fällen wird aus JavaScript heraus eine native Funktion aufgerufen, die intern Activity.request(attributes:contentState:) ausführt und die Aktivität mit den vom JavaScript-Layer übergebenen Anfangsdaten startet.
Wichtig ist dabei, dass der ContentState-Datentyp bereits zur Kompilierzeit in Swift feststehen muss, weil er als typisierte Struktur in der Widget-Extension definiert ist. Ändert sich das Datenmodell auf JavaScript-Seite, etwa weil ein neues Statusfeld hinzukommt, muss die native Swift-Struktur synchron angepasst und die Widget-Extension neu gebaut werden. Ein rein JavaScript-getriebenes, dynamisches Schema ohne native Anpassung ist bei Live Activities architektonisch nicht vorgesehen.
// ios/LiveActivityBridge.swift
import ActivityKit
import ExpoModulesCore
public class LiveActivityBridge: Module {
public func definition() -> ModuleDefinition {
Name("LiveActivityBridge")
Function("startDeliveryActivity") { (orderNumber: String, status: String) in
let attributes = DeliveryActivityAttributes(orderNumber: orderNumber)
let initialState = DeliveryActivityAttributes.ContentState(
status: status, estimatedMinutes: 30, isStale: false
)
_ = try Activity.request(
attributes: attributes,
content: .init(state: initialState, staleDate: nil)
)
}
}
}
4. Lokale Updates versus Push-Updates über ActivityKit
Solange die App im Vordergrund oder kurz im Hintergrund aktiv ist, lässt sich eine laufende Aktivität lokal über activity.update(using:) direkt aus Swift-Code aktualisieren, ausgelöst durch einen Aufruf aus dem React-Native-Layer. Für Aktualisierungen, die eintreffen sollen, während die App komplett terminiert ist, etwa weil sich der Lieferstatus im Backend geändert hat, ist dagegen ein Push-Update über einen dedizierten ActivityKit-Push-Token notwendig, den man von Activity.pushTokenUpdates abonniert und an den eigenen Server überträgt.
Der Server sendet dann eine spezielle APNs-Payload mit dem Header apns-push-type: liveactivity und einem event-Feld, das entweder update für einen neuen Zustand oder end für das Beenden der Aktivität signalisiert. Diese Push-Infrastruktur ist vollständig getrennt vom klassischen Notification-Push-Token einer App, weshalb ein Backend, das bereits reguläre Push-Benachrichtigungen versendet, für Live Activities zusätzliche Logik zur Verwaltung und Zuordnung der Activity-Push-Tokens benötigt.
5. Praxisbeispiel: Live-Lieferstatus nach einer Bestellung
Ein naheliegender Anwendungsfall für einen Magento-angebundenen Shop ist die Lieferverfolgung: Sobald eine Bestellung den Status Versandt erreicht, startet die App eine Live Activity mit der Sendungsnummer als statischem Attribut und dem aktuellen Zustellstatus als dynamischem Inhalt. Jede weitere Statusänderung, etwa Unterwegs, In Zustellung oder Zugestellt, kommt über einen serverseitig ausgelösten Push-Update rein, ohne dass der Nutzer die App je wieder öffnen muss, um informiert zu bleiben.
Für die Umsetzung bedeutet das konkret: Der Zustelldienst-Webhook oder ein regelmäßiger Tracking-Abgleich im Backend löst bei jeder relevanten Statusänderung einen ActivityKit-Push aus, adressiert an den zuvor gespeicherten Push-Token der jeweiligen Aktivität. Erreicht die Sendung den Status Zugestellt, sendet der Server ein end-Event, das die Live Activity nach einer kurzen, vom System vorgegebenen Anzeigedauer automatisch vom Sperrbildschirm entfernt.
// app/hooks/useDeliveryActivity.ts
import { Platform } from "react-native";
import { requireNativeModule } from "expo-modules-core";
const LiveActivityBridge = requireNativeModule("LiveActivityBridge");
export function startDeliveryActivity(orderNumber: string, status: string): void {
if (Platform.OS !== "ios") {
return;
}
LiveActivityBridge.startDeliveryActivity(orderNumber, status);
}
6. Zweites Beispiel: Ein Live-Ticker mit hoher Update-Frequenz
Ein zweiter typischer Anwendungsfall ist ein Live-Ticker, etwa für Sportergebnisse oder Auktions-Countdowns, bei dem sich der Inhalt deutlich häufiger ändert als bei einer Lieferverfolgung. Genau hier zeigt sich eine wichtige praktische Grenze: Apple begrenzt die Anzahl der Push-Updates, die eine Live Activity pro Stunde realistisch verarbeiten kann, über ein internes Budget-System, das bei zu häufigen Updates spätere Push-Zustellungen verzögert oder verwirft, statt sie sofort auszuliefern.
Für einen Live-Ticker mit sekündlichen Änderungen bedeutet das in der Praxis, dass man Updates bewusst bündeln oder auf relevante Ereignisse reduzieren muss, etwa nur bei Toren, Halbzeiten oder signifikanten Score-Änderungen zu pushen, statt jede kleinste Datenänderung einzeln zu übertragen. Wer dieses Budget ignoriert, riskiert, dass die Live Activity auf dem Gerät des Nutzers spürbar veraltete Daten zeigt, obwohl der Server längst aktuellere Push-Updates verschickt hat.
7. Update-Frequenz und Laufzeit-Grenzen im Detail
Eine Live Activity hat standardmäßig eine maximale Laufzeit von acht Stunden ab dem Start, danach beendet das System sie automatisch, unabhängig davon, ob die zugrunde liegende Aufgabe bereits abgeschlossen ist. Über das staleDate-Feld im ContentState lässt sich zusätzlich markieren, ab wann ein bestimmter Inhalt als veraltet gilt, was das System nutzt, um dem Nutzer visuell zu signalisieren, dass keine aktuellen Daten mehr vorliegen, etwa durch eine ausgegraute Darstellung.
Nach dem letzten empfangenen Push-Update verlängert das System die Sichtbarkeit der Aktivität um zusätzliche Zeit, bevor sie endgültig entfernt wird, aktuell rund vier Stunden über die reguläre Achtstundengrenze hinaus, sofern kein explizites end-Event gesendet wurde. Diese Grenzen sind bewusst vom System vorgegeben und lassen sich weder aus der App noch vom Server aus umgehen, weshalb jede Feature-Planung mit Live Activities diese harten Zeitfenster von vornherein einkalkulieren muss.
8. Dynamic-Island-Präsentation: Kompakt, minimal, erweitert
Auf Geräten mit Dynamic Island, ab dem iPhone 14 Pro, erscheint eine Live Activity zusätzlich zur Sperrbildschirm-Darstellung in drei unterschiedlichen Zuständen: kompakt links und rechts der Kamera-Aussparung während normaler Nutzung des Geräts, minimal als kleiner Indikator, wenn eine zweite Aktivität gleichzeitig läuft, und erweitert, sobald der Nutzer lange auf die Dynamic Island drückt oder das Gerät gesperrt ist. Jeder dieser drei Zustände verlangt ein eigenes, bewusst kompaktes SwiftUI-Layout innerhalb der DynamicIsland-Konfiguration.
Der begrenzte Platz in der kompakten Ansicht, faktisch nur wenige Dutzend Pixel rechts und links der Kamera-Aussparung, zwingt zu einer radikalen Informationsreduktion: Bei der Lieferverfolgung reicht dort oft nur ein Icon und eine kurze Zeitangabe, während die vollständige Statusbeschreibung der erweiterten Ansicht vorbehalten bleibt. Diese Design-Beschränkung ist kein Implementierungsdetail, sondern muss bereits in der fachlichen Konzeption des Features mitgedacht werden, bevor die erste Zeile SwiftUI-Code entsteht.
9. Einschränkungen und Testing
Live Activities sind ausschließlich ein iOS-Feature, eine direkte Entsprechung existiert unter Android nicht, allenfalls vergleichbar mit den erst mit Android 16 eingeführten, deutlich anders strukturierten Live Updates für fortlaufende Benachrichtigungen. Eine plattformübergreifende React-Native-App muss diese Funktionalität also grundsätzlich als iOS-exklusives Feature behandeln und für Android entweder eine reguläre Notification-basierte Alternative anbieten oder das Feature dort schlicht weglassen.
Zum Testen genügt für lokale Updates ein Debug-Build im Simulator, für Push-Updates braucht es dagegen zwingend ein echtes Gerät mit korrekt eingerichteter ActivityKit-Push-Entitlement, weil der Simulator keine echten APNs-Push-Tokens ausstellt. Vor der Store-Freigabe prüft Apple explizit, ob eine Live Activity tatsächlich relevante, sich verändernde Informationen zeigt und nicht als reines Werbeformat missbraucht wird, ein Punkt, der bei der Review häufiger zu Rückfragen führt als bei regulären Notifications.
| Aspekt | Live Activity (iOS) | Reguläre Push-Notification |
|---|---|---|
| Sichtbarkeit | Dauerhaft auf Sperrbildschirm und Dynamic Island verankert | Erscheint kurz, verschwindet nach Interaktion |
| Maximale Laufzeit | 8 Stunden, mit Push bis zu rund 12 Stunden | Keine Laufzeitbegrenzung, da einmaliges Ereignis |
| Update-Mechanismus | Lokal via Activity.update oder ActivityKit-Push | Einzelne, unabhängige Push-Zustellung |
| Update-Frequenz | Durch Apples Budget-System begrenzt | Praktisch unbegrenzt, aber Rate-Limiting durch APNs |
| Plattform | Nur iOS 16.1 und neuer | iOS und Android gleichermaßen verfügbar |
Mironsoft
React-Native-App-Entwicklung und Magento-Anbindung
Eine mobile App zum Magento-Shop, die wirklich rund läuft?
Wir entwickeln React-Native-Apps, die sauber an die Magento REST- oder GraphQL-API angebunden sind, von der ersten Codezeile bis zur Veröffentlichung im App Store und bei Google Play.
App-Konzeption
Architektur und Feature-Umfang einer Magento-angebundenen App gemeinsam planen.
Magento-API-Integration
Produktkatalog, Warenkorb und Checkout sauber an die Shop-API anbinden.
Store-Veröffentlichung
App Store- und Google-Play-Freigabeprozess ohne Stolperfallen begleiten.
10. Zusammenfassung
Live Activities: Das Wichtigste auf einen Blick
Plattform
Ausschließlich iOS ab Version 16.1, kein direktes Android-Äquivalent.
Technische Basis
Eigene Widget-Extension mit ActivityKit und WidgetKit, kein Pure-JS-Ansatz.
Update-Wege
Lokal über Activity.update oder per Push über ActivityKit-Push-Token.
Laufzeit-Grenze
8 Stunden Standard, bis zu rund 12 Stunden mit aktiven Push-Updates.