Разработка 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 недель. Стоимость рассчитывается индивидуально, но мы всегда даём точную оценку до начала работ.
Получите консультацию — свяжитесь с нами, чтобы обсудить ваш проект.







