Розробка Live Activities для iOS
Live Activities — функція iOS 16.1+, що дозволяє додатку відображати динамічний контент прямо на екрані блокування та в Dynamic Island (iPhone 14 Pro+). Таксі їде до вас — прогресс-бар на Lock Screen оновлюється в реальному часі. Матч індеться — рахунок в Dynamic Island без розблокування телефону.
Живуть до 8 годин (або 12 з явним продовженням через ActivityKit), потім система скриває їх. Після 12 годин — примусове завершення.
ActivityKit: архітектура
Live Activity будується на трьох речах: ActivityAttributes (статичні дані, задані при старті), ContentState (динамічні дані, оновлювані через push або API), та SwiftUI View для трьох представлень: Lock Screen / Standby, Dynamic Island Compact, Dynamic Island Expanded.
struct DeliveryAttributes: ActivityAttributes {
// Статика — не змінюється під час життя
let orderId: String
let restaurantName: String
struct ContentState: Codable, Hashable {
// Динаміка — оновлюється
var status: DeliveryStatus
var estimatedMinutes: Int
var courierLocation: CLLocationCoordinate2D?
}
}
Старт з додатка:
let attributes = DeliveryAttributes(orderId: "1234", restaurantName: "Піцца Південь")
let state = DeliveryAttributes.ContentState(status: .preparing, estimatedMinutes: 30)
let content = ActivityContent(state: state, staleDate: Date().addingTimeInterval(600))
let activity = try Activity.request(
attributes: attributes,
content: content,
pushType: .token // Отримати push token для дистанційних оновлень
)
staleDate — дата, після якої контент вважається застарілим та система може показати індикатор неактуальності. Для таксі: Date() + estimatedMinutes * 60.
Оновлення через Push Notifications
Найнадійніший спосіб оновлювати Live Activity з сервера — ActivityKit Push Notifications (не звичайні APNs).
Push payload:
{
"aps": {
"timestamp": 1698765432,
"event": "update",
"content-state": {
"status": "in_delivery",
"estimatedMinutes": 12
},
"alert": {
"title": "Курьєр виїхав",
"body": "Очікуйте через 12 хвилин"
}
}
}
event: "end" — завершити Live Activity через push. alert в push для Live Activity — відображається як оновлення в Dynamic Island з тактильним відгуком.
Push token для Live Activity відрізняється від звичайного APNs token. Отримуємо через activity.pushTokenUpdates AsyncSequence: потрібно слухати оновлення, тому що token може змінюватися.
Task {
for await tokenData in activity.pushTokenUpdates {
let token = tokenData.map { String(format: "%02x", $0) }.joined()
await sendTokenToServer(token)
}
}
SwiftUI Views для різних зон
struct DeliveryLiveActivityView: View {
let context: ActivityViewContext<DeliveryAttributes>
var body: some View {
// Lock Screen / StandBy
HStack {
Image(systemName: statusIcon(context.state.status))
VStack(alignment: .leading) {
Text(context.attributes.restaurantName)
.font(.headline)
Text("~\(context.state.estimatedMinutes) хв")
.font(.subheadline)
}
Spacer()
DeliveryProgressView(status: context.state.status)
}
.padding()
}
}
DynamicIsland builder для Dynamic Island:
DynamicIsland {
// Expanded — довгий тап
DynamicIslandExpandedRegion(.leading) {
Image(systemName: "bicycle")
}
DynamicIslandExpandedRegion(.trailing) {
Text("\(context.state.estimatedMinutes) хв")
}
DynamicIslandExpandedRegion(.bottom) {
Text("Курьєр: \(courierName)")
}
} compactLeading: {
Image(systemName: "bicycle")
} compactTrailing: {
Text("\(context.state.estimatedMinutes)хв")
} minimal: {
Image(systemName: "bicycle")
}
Compact — дві зони по бокам «острова» при свернутому стані. Minimal — одна маленька іконка коли активні кілька Live Activities.
Обмеження, які важливо знати
Розмір ContentState — не більше 4KB в ActivityKit push payload. Для координат курьєра: не передавати весь трек, лише поточну позицію.
Додаток має бути на переднему плані або мати Background Push для старту Live Activity. Не можна стартувати з фону без дії користувача (з iOS 17.2 — можна через ActivityAuthorizationInfo().areActivitiesEnabled).
Симулятор підтримує Live Activities з iOS 16.2 Simulator. Dynamic Island — лише на фізичному устройстве iPhone 14 Pro/Pro Max та новішому.
Термін: 3-5 днів для базової реалізації з push-оновленнями. Вартість залежить від складності UI та наявності серверної частини.







