Розробка Live Activities для iOS під ключ
Уявіть: додаток доставки показує прогрес замовлення прямо на екрані блокування, користувач не заходить у телефон — просто бачить, що кур'єр за рогом. Ми реалізували такі рішення для кількох клієнтів і знаємо всі нюанси. Одне з таких рішень збільшило retention на 20% у перший місяць після впровадження. Замовте розробку Live Activities у професіоналів.
Live Activities — функція iOS 16.1+, яка дозволяє додатку відображати динамічний контент на екрані блокування та в Dynamic Island (починаючи з iPhone 14 Pro). Таксі їде до вас — прогрес-бар оновлюється в реальному часі. Матч триває — рахунок у Dynamic Island без розблокування. За даними Apple, користувачі взаємодіють з Live Activities в середньому в 3 рази частіше, ніж зі звичайними сповіщеннями (Human Interface Guidelines, Apple).
Що дають Live Activities вашому бізнесу?
Конкуренція за увагу користувача величезна. Live Activities — єдиний спосіб бути на виду, не відволікаючи від інших завдань. За нашими даними, впровадження Live Activities збільшує retention на 20–30%. Сервіси таксі, доставки, фітнес-трекери, спортивні додатки вже активно це використовують. Якщо ви не використовуєте Live Activities — ви втрачаєте аудиторію.
Як ми реалізуємо Live Activities: стек і приклади
Ми використовуємо Swift 5.9+, SwiftUI, Combine. Основний фреймворк — ActivityKit. Архітектура будується на трьох речах: ActivityAttributes (статичні дані), ContentState (динамічні дані) та SwiftUI View для трьох представлень.
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?
Найнадійніший спосіб — ActivityKit Push Notifications (не звичайні APNs). Push payload:
{
"aps": {
"timestamp": 1698765432,
"event": "update",
"content-state": {
"status": "in_delivery",
"estimatedMinutes": 12
}
}
}
Push token для Live Activity отримуємо через activity.pushTokenUpdates AsyncSequence. Оновлення token можуть відбуватися, тому слухаємо потік:
Task {
for await tokenData in activity.pushTokenUpdates {
let token = tokenData.map { String(format: "%02x", $0) }.joined()
await sendTokenToServer(token)
}
}
SwiftUI-види для всіх зон
struct DeliveryLiveActivityView: View {
let context: ActivityViewContext<DeliveryAttributes>
var body: some View {
HStack {
Image(systemName: statusIcon(context.state.status))
VStack(alignment: .leading) {
Text(context.attributes.restaurantName)
.font(.headline)
Text("\(context.state.estimatedMinutes) хв")
}
Spacer()
DeliveryProgressView(status: context.state.status)
}
.padding()
}
}
DynamicIsland builder для Dynamic Island:
DynamicIsland {
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")
}
Чому Live Activities складніше, ніж здається?
Під капотом ActivityKit — складна система управління ресурсами. Розмір ContentState у push не має перевищувати 4 KB. Якщо перевищити, сповіщення відкидається. Ми зіткнулися з цим у проекті доставки: спробували передати повний трек кур'єра (100+ точок) — push не проходив. Рішення — передавати тільки поточну позицію, а історію зберігати локально.
Інша складність — стан stale. Якщо не оновлювати активність вчасно, вона «зависає» з застарілими даними. Потрібно встановлювати staleDate і оновлювати по тригеру. В одному кейсі ми забули обробити закриття замовлення — активність висіла добу. Зараз це автоматизовано.
Яких помилок варто уникати при впровадженні?
| Типова помилка | Наслідки | Як уникнути |
|---|---|---|
| Занадто великий payload (>4KB) | Push не доставляється | Стискайте дані, використовуйте статику в Attributes |
| Оновлення з фонового режиму без push | Не спрацьовує, активність зависає | Використовуйте ActivityKit Push Notifications |
| Ігнорування стану stale | Показує застарілі дані | Встановлюйте staleDate і оновлюйте по ньому |
| Неправильне налаштування push token | Сповіщення не приходять | Підписуйтесь на pushTokenUpdates і передавайте на сервер |
Процес роботи: від ідеї до публікації
| Етап | Дії | Результат |
|---|---|---|
| Аналітика | Вивчаємо ваш сценарій, визначаємо типи даних та UI | Технічне завдання |
| Проектування | Розробка архітектури ActivityAttributes та ContentState | Діаграма даних |
| Реалізація | Створення SwiftUI-видів, інтеграція ActivityKit, налаштування push | Робочий прототип |
| Тестування | Перевірка на реальних пристроях, симуляція сценаріїв | Звіт про тестування |
| Деплой | Підготовка метаданих, публікація в App Store | Live Activity у продакшені |
Що входить у результат
- Вихідний код на Swift 5.9+ з коментарями
- SwiftUI-види для Lock Screen та Dynamic Island
- Серверна частина для відправки push-повідомлень (якщо потрібно)
- Документація з підтримки та оновлення
- Навчання вашого розробника (опціонально)
Обмеження, які важливо враховувати
- Розмір
ContentState— не більше 4KB у push payload. - Додаток має бути на передньому плані для старту (з останніх версій iOS можна через
ActivityAuthorizationInfo().areActivitiesEnabled). - Dynamic Island доступний тільки на фізичних iPhone 14 Pro/Pro Max+.
- Симулятор підтримує Live Activities з відповідною версією iOS.
Гарантуємо якість: кожна активність проходить перевірку на відповідність стандарту StoreKit та Human Interface Guidelines. Оцінимо ваш проект безкоштовно — напишіть нам.
Строки та вартість
Базова реалізація з push-оновленнями — від 3 до 5 робочих днів. Складні UI та серверна частина можуть збільшити строк до 2 тижнів. Вартість розраховується індивідуально, але ми завжди даємо точну оцінку до початку робіт.
Отримайте консультацію — зв'яжіться з нами, щоб обговорити ваш проект.







