Live Activity — ένα δυναμικό widget στην οθόνη κλειδώματος του iPhone και στο Dynamic Island που εμφανίζει πληροφορίες σε πραγματικό χρόνο: κατάσταση παράδοσης, αθλητικά σκορ, χρονοδιακόπτες και αναπαραγωγή μουσικής. Υλοποιείται μέσω του ActivityKit (Swift, iOS 16.1+) μαζί με το WidgetKit. Το Live Activity ενημερώνεται τοπικά ή μέσω ειδοποιήσεων push, υποστηρίζει πολλαπλές καταστάσεις και τερματίζεται από το σύστημα μετά το τέλος του συμβάντος. Περισσότερα στο ActivityKit Documentation.
Κύρια σημεία
Live Activity — μια επέκταση του WidgetKit που εμφανίζει δυναμικό περιεχόμενο στην οθόνη κλειδώματος του iPhone και στο Dynamic Island. Σε αντίθεση με το στατικό widget που ενημερώνεται σύμφωνα με το χρονόμετρο του συστήματος, το Live Activity εκκινείται από μια εφαρμογή και ζει για περιορισμένο χρόνο — έως 8 ώρες για ενεργή Activity και έως 4 ώρες μετά την ολοκλήρωση. Ο χρήστης βλέπει τα τρέχοντα δεδομένα χωρίς να ξεκλειδώσει τη συσκευή: κατάσταση παραγγελίας παράδοσης, απόσταση από τον προορισμό σε ταξί, αποτέλεσμα αγώνα ή πρόοδο προπόνησης.
ActivityKit — πλαίσιο για εργασία με Live Activities, που παρουσιάστηκε στο iOS 16.1. Παρέχει API για αίτημα, ενημέρωση και τερματισμό Activity. Το Activity είναι ένα αντικείμενο με περιεχόμενο και κατάσταση. Το περιεχόμενο (ActivityContent) ορίζει στατικά δεδομένα, ενώ η κατάσταση (ActivityState) — δυναμικά δεδομένα που αλλάζουν με την πάροδο του χρόνου. Το σύστημα αποφασίζει μόνο του πότε θα κάνει render τη νέα κατάσταση — αυτό εξοικονομεί μπαταρία και εγγυάται ομαλότητα κινουμένων σχεδίων.
Κάθε Live Activity αναγνωρίζεται μοναδικά από το ActivityID και συνδέεται με μία διεργασία — την εφαρμογή που τη δημιούργησε. Το σύστημα μπορεί να τερματίσει την Activity σε περίπτωση ανεπαρκούς μνήμης ή χαμηλής μπαταρίας. Ο προγραμματιστής λαμβάνει ειδοποίηση για τον αναγκαστικό τερματισμό μέσω του εκπροσώπου ActivityKit και μπορεί να αποθηκεύσει την τελευταία κατάσταση για επαναφορά.
Η αρχιτεκτονική Live Activity βασίζεται σε δύο πλαίσια: Το WidgetKit είναι υπεύθυνο για την απόδοση των προβολών SwiftUI, το ActivityKit — για τον κύκλο ζωής της Activity. Ο προγραμματιστής δημιουργεί ένα WidgetBundle με υποστήριξη LiveActivityConfiguration. Κάθε διαμόρφωση ορίζει τον τύπο δεδομένων (Attributes και State) και το SwiftUI View που αποδίδεται από το σύστημα στο Lock Screen και Dynamic Island. Τα δεδομένα μεταφέρονται μέσω ActivityAttributes — μια struct με πεδία let για περιεχόμενο και var για κατάσταση.
| Στοιχείο | Σκοπός | API |
|---|---|---|
| Attributes | Στατικά δεδομένα ολόκληρης της Activity | let name: String, let icon: String |
| ContentState | Δυναμική κατάσταση, που αλλάζει κατά την ενημέρωση | var progress: Double, var status: Status |
| Activity | Αντικείμενο αιτήματος και διαχείρισης Activity | Activity.request(attributes:content:) |
| PushToken | Token για ενημερώσεις push από διακομιστή | activity.pushToken publisher |
| ActivityUI | SwiftUI View για Lock Screen και Dynamic Island | LockScreenView, ExpandedView, CompactView |
Ο κύκλος ζωής της Activity περιλαμβάνει τρεις φάσεις: ενεργή (το σύστημα εμφανίζει και ενημερώνει), τελική (η δραστηριότητα ολοκληρώθηκε αλλά το UI είναι ακόμα ορατό για 4 ώρες), διαγραμμένη (το σύστημα αφαιρεί το UI). Η εφαρμογή μπορεί να τερματίσει την Activity ανά πάσα στιγμή. Το σύστημα επίσης τερματίζει αναγκαστικά την Activity — για παράδειγμα, κατά την επανεκκίνηση της συσκευής ή τη λήξη του ορίου των 8 ωρών.
import ActivityKit
struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable & Hashable {
var status: DeliveryStatus
var estimatedMinutes: Int
}
var orderNumber: String
var restaurantName: String
}
WidgetBundle καταχωρεί το Live Activity μέσω του μακροεντολέα @main: το widget επιστρέφει μια λίστα διαμορφώσεων, συμπεριλαμβανομένης της LiveActivityConfiguration. Βάσει αυτής της διαμόρφωσης, το σύστημα γνωρίζει ποιους τύπους δεδομένων να περιμένει και πώς να αποδώσει το UI σε διαφορετικές καταστάσεις — συμπαγή, ελάχιστη και εκτεταμένη για το Dynamic Island.
Η δημιουργία Activity ξεκινά με ένα αίτημα προς το ActivityKit. Η εφαρμογή καλεί το Activity.request(attributes:content:pushType:) με αρχικά δεδομένα. Το σύστημα ελέγχει εάν το Dynamic Island είναι διαθέσιμο στη συσκευή και επιστρέφει ένα αντικείμενο Activity. Το αίτημα μπορεί να αποτύχει εάν ξεπεραστεί το όριο ενεργών Activity — συνήθως όχι περισσότερες από 5 ταυτόχρονα. Μετά από επιτυχημένο αίτημα, το σύστημα εμφανίζει το widget στο Lock Screen και, αν είναι δυνατόν, στο 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 για Live Activity χρησιμοποιεί τις δομές LockScreenView, ExpandedView και CompactView από το WidgetKit. Η View λαμβάνει πλαίσιο (ActivityViewContext) με τα τρέχοντα χαρακτηριστικά και κατάσταση. Η ενημέρωση της View γίνεται αυτόματα όταν λαμβάνεται νέα κατάσταση από το σύστημα. Το Live Activity υποστηρίζει μόνο περιορισμένο σύνολο στοιχείων SwiftUI — Text, Image, HStack, VStack και μερικούς τροποποιητές.
Κάθε Live Activity View πρέπει να είναι ελαφριά και γρήγορη — το σύστημα αρνείται να αποδώσει βαριές προβολές. Το όριο χρόνου απόδοσης — 30 ms ανά καρέ. Τα κινούμενα σχέδια περιορίζονται σε μεταβάσεις συστήματος μεταξύ καταστάσεων — προσαρμοσμένα κινούμενα σχέδια στο Live Activity δεν είναι διαθέσιμα. Η απόδοση εκτελείται στο παρασκήνιο από τη διεργασία WidgetKit με προτεραιότητα απόκρισης του Lock Screen.
Τοπική ενημέρωση — η εφαρμογή ενημερώνει την κατάσταση Activity καλώντας το activity.update(using:). Η μέθοδος λαμβάνει νέο ContentState και προαιρετικό AlertConfiguration για εμφάνιση ειδοποίησης κατά την ενημέρωση. Οι τοπικές ενημερώσεις είναι γρήγορες — το σύστημα επανασχεδιάζει την View στον επόμενο κύκλο απόδοσης, συνήθως εντός 1–2 δευτερολέπτων. Για συχνές ενημερώσεις (χρονοδιακόπτης, χρονόμετρο) χρησιμοποιήστε την τοπική λειτουργία — είναι πιο αξιόπιστη και ταχύτερη από την 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 — ο διακομιστής στέλνει μια ειδοποίηση push ActivityKit με νέα κατάσταση σε μορφή JSON. Για αυτό, η εφαρμογή λαμβάνει το pushToken από τον εκδότη activity.pushToken και το μεταβιβάζει στον διακομιστή. Ο διακομιστής στέλνει ένα αίτημα POST στα APNs με ωφέλιμο φορτίο που περιέχει το νέο ContentState. Το σύστημα λαμβάνει το push, αποκωδικοποιεί την κατάσταση και ενημερώνει το Live Activity χωρίς τη συμμετοχή της εφαρμογής — αυτό επιτρέπει την ενημέρωση της Activity ακόμη και όταν η εφαρμογή είναι κλειστή.
Οι ενημερώσεις push είναι πιο οικονομικές από τις τοπικές για σπάνιες ενημερώσεις (κατάσταση παράδοσης κάθε 5–10 λεπτά) — η εφαρμογή δεν χρειάζεται να διατηρεί σύνδεση δικτύου. Για συχνές ενημερώσεις κάθε 1–2 δευτερόλεπτα χρησιμοποιήστε την τοπική μέθοδο. Το ωφέλιμο φορτίο του διακομιστή περιέχει μόνο τα μεταβλητά πεδία του ContentState — τα στατικά δεδομένα Attributes αποστέλλονται μόνο κατά τη δημιουργία της Activity.
Dynamic Island — μια περιοχή υλικού-λογισμικού στο iPhone 14 Pro, 15 Pro και νεότερα που προσαρμόζεται στο περιεχόμενο του Live Activity. Το σύστημα εμφανίζει αυτόματα την Activity σε τρεις λειτουργίες: συμπαγή (εικονίδιο + σύντομο κείμενο αριστερά από την εγκοπή), ελάχιστη (μόνο εικονίδιο) και εκτεταμένη (ορθογώνιο 300pt με πληροφορίες). Ο προγραμματιστής δεν διαχειρίζεται άμεσα αυτές τις λειτουργίες — το σύστημα επιλέγει τη λειτουργία βάσει προτεραιότητας και διαθέσιμου χώρου.
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 υποστηρίζει διαδραστικότητα — ο χρήστης αγγίζει την περιοχή και εισέρχεται στην εφαρμογή ή ανοίγει την εκτεταμένη προβολή. Το άγγιγμα της συμπαγούς λειτουργίας μεταβαίνει στην εκτεταμένη λειτουργία, και το σύρσιμο προς τα αριστερά κρύβει την Activity στην ελάχιστη λειτουργία. Τα κουμπιά στην εκτεταμένη λειτουργία (pause/cancel) διαχειρίζονται μέσω Link από το SwiftUI — το σύστημα εκκινεί την εφαρμογή με ένα deep link URL, η επεξεργασία γίνεται στο UIApplicationDelegate.
Περιορισμοί Dynamic Island: πλάτος εκτεταμένης λειτουργίας — έως 300pt, συμπαγές κείμενο — έως 30 χαρακτήρες. Τα χρώματα και οι γραμματοσειρές αντιστοιχούν στο θέμα συστήματος — η προσαρμογή είναι περιορισμένη. Οι κινήσεις μετάβασης μεταξύ λειτουργιών είναι συστημικές και δεν μπορούν να ρυθμιστούν. Εάν πολλές εφαρμογές έχουν ενεργές Activity, το Dynamic Island τις εμφανίζει με προτεραιότητα βάσει χρόνου εκκίνησης και τύπου περιεχομένου.
Συχνές ερωτήσεις
Ένα συνηθισμένο WidgetKit widget εμφανίζει στατικές πληροφορίες και ενημερώνεται σύμφωνα με το χρονόμετρο του συστήματος με ελάχιστο διάστημα 15–30 λεπτών. Το Live Activity δείχνει δυναμικά δεδομένα σε πραγματικό χρόνο στην οθόνη κλειδώματος και στο Dynamic Island. Το Live Activity εκκινείται από την εφαρμογή, ζει έως 8 ώρες και τερματίζεται από το σύστημα μετά το τέλος του συμβάντος, σε αντίθεση με το widget που υπάρχει μόνιμα.
Το Live Activity υποστηρίζει δύο λειτουργίες ενημέρωσης: τοπική — η εφαρμογή ενημερώνει την κατάσταση μέσω του API ActivityKit ανά πάσα στιγμή, και push — ο διακομιστής στέλνει μια ειδοποίηση push ActivityKit που το σύστημα μετατρέπει σε νέα κατάσταση widget. Σε χαμηλή μπαταρία, το σύστημα μπορεί να παγώσει το Live Activity μέχρι τη σύνδεση του φορτιστή.
Τα Live Activities είναι διαθέσιμα σε iPhone με iOS 16.1 και νεότερο. Σε iPhone 14 Pro και νεότερα, το Live Activity εμφανίζεται επίσης στο Dynamic Island. Σε iPad, το Live Activity υποστηρίζεται μόνο στην οθόνη κλειδώματος — το Dynamic Island δεν υπάρχει σε iPad. Το Apple Watch δεν υποστηρίζει άμεσα Live Activities, αλλά μπορεί να εμφανίζει ειδοποιήσεις ολοκλήρωσης.
Το σύστημα περιορίζει τον αριθμό των ενεργών Live Activities — συνήθως όχι περισσότερες από 5 ταυτόχρονα για όλες τις εφαρμογές. Κατά την προσπάθεια υπέρβασης του ορίου, το ActivityKit επιστρέφει σφάλμα. Κάθε Live Activity μπορεί να έχει πολλές καταστάσεις — για παράδειγμα, αναμονή, σε διαμετακόμιση, παραδόθηκε για παραγγελία φαγητού. Μετά την ολοκλήρωση, η Activity παραμένει στο UI για άλλες 4 ώρες.
Ναι, η εφαρμογή πρέπει να ζητήσει άδεια για αποστολή ειδοποιήσεων — το Live Activity χρησιμοποιεί το κανάλι ειδοποιήσεων του συστήματος. Ο χρήστης μπορεί να απενεργοποιήσει το Live Activity για μια συγκεκριμένη εφαρμογή στις ρυθμίσεις. Κατά την πρώτη εκκίνηση, το ActivityKit εμφανίζει ένα παράθυρο διαλόγου με αίτημα άδειας. Χωρίς άδεια, το αίτημα Activity αποτυγχάνει με σφάλμα.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης