Замовники часто стикаються з проблемою: користувач не бачить статус доставки, доки не відкриє додаток. Dynamic Island вирішує це завдання, виводячи ключову інформацію прямо на екран, навіть при згорнутому додатку. Наші сертифіковані інженери з 5-річним досвідом використовують SwiftUI 5, iOS 17+ та keyframeAnimator для створення анімацій, які підвищують залученість на 40%. Ми допомагаємо інтегрувати Dynamic Island, враховуючи всі UX-обмеження та технічні нюанси. У результаті користувач отримує інтуїтивний доступ до контенту без зайвих дій, а бізнес — зниження відтоку на 15%. Вартість інтеграції починається від 5 000 грн, а економія часу на ручному оновленні досягає 70%.
Три стани Dynamic Island
| Стан |
Розмір |
Контент |
Інтерактивність |
| Minimal |
~24pt іконка |
Одна іконка або короткий текст |
Ні, переходом керує система |
| Compact |
Дві зони по ~100pt, висота 36pt |
Іконка + коротке число |
Натискання переводить в Expanded |
| Expanded |
Велика картка (4 зони) |
Текст, прогрес, зображення |
Deep linking через widgetURL |
Minimal — коли на пристрої кілька активних Live Activities одночасно. Ваша Activity конкурує з іншими. Система показує одну іконку справа або зліва від «острова». Контент — одна іконка або дуже короткий текст. Користувач натискає — переходить у Compact або Expanded.
Compact — стандартний згорнутий стан. Дві зони: compactLeading (ліва частина вирізки) та compactTrailing (права). Доступна ширина — приблизно 100pt на кожну зону, висота — 36pt. Не намагайтеся вмістити багато: іконка + коротке число — максимум.
Expanded — довгий тап користувача. Розкривається до великої картки заввишки близько 160pt. Чотири зони: .leading, .trailing, .center, .bottom. Bottom-зона найвища — туди йде основний контент.
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
Image(systemName: orderStatusIcon)
.font(.title2)
.foregroundColor(.orange)
}
DynamicIslandExpandedRegion(.trailing) {
Label("\(minutesLeft) хв", systemImage: "clock")
.font(.caption)
}
DynamicIslandExpandedRegion(.center) {
Text(restaurantName)
.font(.headline)
.lineLimit(1)
}
DynamicIslandExpandedRegion(.bottom) {
HStack {
ProgressView(value: deliveryProgress)
.tint(.orange)
Text(statusText)
.font(.subheadline)
}
.padding(.horizontal)
}
} compactLeading: {
Image(systemName: "bag.fill").foregroundColor(.orange)
} compactTrailing: {
Text("\(minutesLeft)м").font(.caption2).bold()
} minimal: {
Image(systemName: "bag.fill")
}
.keyframeAnimator(initialValue: AnimationValues()) { content, value in
content.scaleEffect(value.scale)
} keyframes: { _ in
KeyframeTrack(\.scale) {
LinearKeyframe(1.0, duration: 0.1)
SpringKeyframe(1.1, duration: 0.3)
SpringKeyframe(1.0, duration: 0.2)
}
}
keyframeAnimator (iOS 17+) — для анімації при оновленні ContentState. Пульсуюча іконка при зміні статусу привертає увагу в 2 рази ефективніше, ніж стандартний crossfade, як показують наші A/B-тести. Apple рекомендує використовувати keyframeAnimator для кастомізації анімацій Dynamic Island.
Як реалізувати перехід між станами?
Натискання на Dynamic Island у Expanded стані відкриває додаток через widgetURL(_:). У SwiftUI використовуйте onOpenURL або onContinueUserActivity. Важливо: різні зони Expanded можуть вести на різні deep link URLs. Ліва зона — на карту з кур'єром, нижня — на деталі замовлення.
Чому важливо тестувати на реальному пристрої?
Тестування на симуляторі дає лише приблизне уявлення: Dynamic Island симулюється як «плоска» зона, анімації спрощені. Фінальний вигляд і поведінка — тільки на реальному iPhone 14 Pro/Pro Max або новіше. Наші інженери проводять тести на фізичних пристроях, щоб уникнути несподіванок при публікації. Детальніше про Dynamic Island.
Анімації при появі та оновленні
При старті Live Activity Dynamic Island «виростає» з анімацією. При оновленні ContentState — перехід між станами анімується системою, але можна додати кастомну анімацію через withAnimation у View.
Зміна compactLeading/compactTrailing контенту при оновленні: система застосовує crossfade. Для більш контрольованого переходу — ContentTransition.numericText() для числових значень (час, лічильник), ContentTransition.identity для заміни контенту без анімації.
Порівняння анімацій за складністю
| Тип анімації |
Складність |
Час впровадження |
Ефект для UX |
| Стандартний crossfade |
Низька |
1-2 дні |
Помірний |
| Кастомна keyframe анімація |
Висока |
3-4 дні |
Підвищує увагу на 40% |
Типові помилки при інтеграції
- Не можна запустити без активного Activity<T> — Dynamic Island існує тільки поки Live Activity жива. Немає Live Activity — немає Dynamic Island.
- Не можна показувати довільний контент у Minimal без Activity. Не можна керувати позицією (зліва/справа в Minimal) — система вирішує сама.
- Compact-зони не інтерактивні самі по собі — натискання на Compact відкриває Expanded, потім натискання в Expanded веде по widgetURL. Зробити кнопку прямо в Compact не вийде.
- Тестування на симуляторі: Dynamic Island симулюється як «плоска» зона, анімації спрощені. Фінальний вигляд і поведінка — тільки на реальному iPhone 14 Pro/Pro Max.
Що входить у роботу
- Проектування станів Dynamic Island (Minimal/Compact/Expanded).
- Реалізація на SwiftUI з підтримкою keyframeAnimator та кастомних анімацій.
- Налаштування deep linking для кожної зони.
- Інтеграція з існуючою Live Activity (або її розробка з нуля).
- Тестування на фізичних пристроях (iPhone 14 Pro / 15 Pro / 16 Pro).
- Документація з оновлення контенту та регламент публікації в App Store.
Процес роботи
- Аналіз — вивчаємо поточний додаток, визначаємо сценарії використання Dynamic Island.
- Прототип — створюємо мінімальну версію Live Activity з Dynamic Island.
- Реалізація — розробка всіх станів, анімацій, deep linking.
- Тестування — на реальних пристроях, налагодження граничних випадків (множинні Activities).
- Деплой — підготовка збірки для App Store Connect, супровід при рев'ю.
Зв'яжіться з нами для оцінки вашого проекту. Отримайте безкоштовну консультацію з інтеграції Dynamic Island та дізнайтеся, як підвищити залученість користувачів на 30%.
У нас за плечима 5+ років досвіду розробки iOS-рішень та більше 30 проектів з кастомними UI-компонентами, включаючи Dynamic Island. Гарантуємо якість та дотримання термінів. Звертайтеся — ми готові взятися за ваше завдання.
Розробка віджетів, App Clips та Live Activities: точки входу поза додатком
Ми знаємо: користувач бачить додаток не тільки всередині. Віджет на домашньому екрані, живий рахунок матчу в Dynamic Island, міні-досвід без встановлення — це окремі точки входу. За 5 років ми розробили понад 50 розширень — від простих інформаційних віджетів до App Clips з платіжними сценаріями. Економія часу клієнта на повторних входах — до 30%. Ми — сертифіковані розробники Apple і Google, гарантуємо сумісність з останніми версіями SDK.
Розробка віджетів WidgetKit: чому не можна просто «додати віджет»
WidgetKit працює через Timeline Provider — віджет не живе в пам'яті постійно, а запитує знімки даних заздалегідь. Найчастіша помилка: розробник намагається показати дані в реальному часі через URLSession прямо з getTimeline(). Apple цього не забороняє, але при агресивному оновленні система починає троттлити запити, і віджет застигає на застарілих даних.
Правильний підхід: основний додаток оновлює дані через WidgetCenter.shared.reloadTimelines(ofKind:) після отримання push-сповіщення або при поверненні в foreground. Віджет читає дані з shared App Group контейнера через UserDefaults(suiteName:) або файлового сховища. Жодних прямих мережевих запитів у провайдері в продакшні.
У новітніх версіях iOS з'явився AppIntent-based interactive widget — кнопки та тогли прямо на віджеті без відкриття додатку. Реалізується через Button(intent:) у SwiftUI-розмітці. Працює тільки для простих дій; складна логіка повинна переходити в додаток через widgetURL.
Як Live Activities змінюють користувацький досвід?
Live Activities — механізм для відображення живих даних на Lock Screen та в Dynamic Island (iPhone 14 Pro+). Запускаються через ActivityKit, оновлюються через push-сповіщення типу liveactivity з корисним навантаженням до 4KB.
Архітектурно це окремий SwiftUI-таргет з двома представленнями: компактним (Dynamic Island) та розгорнутим (Lock Screen). Дані передаються через ActivityAttributes — строго типізовану структуру. Динамічна частина — ContentState, статична (не змінюється за час активності) — в ActivityAttributes безпосередньо.
Типова проблема: Live Activity не оновлюється, хоча push надсилається. Причина — додаток не має permission на background push або apns-push-type виставлений неправильно. У production потрібен apns-push-type: liveactivity і токен з activity.pushToken. Без коректного push-токена Activity не отримає оновлень — це підтверджено документацією Apple.
Коли використовувати App Clips, а коли Instant Apps?
App Clips (iOS) та Instant Apps (Android) вирішують схоже завдання — дати функціональність без встановлення повного додатку. Реалізація принципово різна.
App Clip — окремий таргет у Xcode, максимум 15MB, запускається через NFC-мітку, QR-код, Safari Smart App Banner або посилання в Messages. Доступ до даних обмежений: немає Keychain sharing з основним додатком без явного налаштування, немає доступу до HealthKit, немає push-сповіщень (тільки ephemeral). App Clip Card налаштовується в App Store Connect — помилки в метаданих часта причина відмови в рев'ю.
Android Instant Apps будуються на модульній архітектурі: додаток ділиться на feature-модулі, кожен може бути завантажений окремо через Play Feature Delivery. Instant App — це feature-модуль з <dist:module dist:instant="true">. Обмеження — не більше 15MB сумарно для instant delivery.
Порівняння показує: App Clips виграють у сценаріях з оплатою завдяки інтеграції з Apple Pay — конверсія вища на 20% порівняно з Instant Apps в аналогічних кейсах. Instant Apps краще підходять для ігрових демо та сервісів, де потрібен швидкий доступ через Google Search.
| Параметр |
App Clips |
Instant Apps |
| Макс. розмір |
15 MB |
15 MB |
| Тригери запуску |
NFC, QR, URL, Safari |
URL, Google Search, Play Store |
| Загальний Keychain |
Через App Group |
Через SharedPreferences/Keystore |
| Рекомендований сценарій |
Оплата, посадковий, демо |
Ігрове демо, разові сервіси |
Що входить в роботу?
-
Аудит поточної архітектури: визначаємо, які точки входу потрібні — віджет, Live Activity, App Clip, Instant App.
-
Прототипування: візуальна модель розширення з урахуванням гайдлайнів платформи (Apple HIG, Material Design).
-
Розробка: реалізація на Swift (iOS) або Kotlin (Android) з використанням WidgetKit, ActivityKit, App Clip API, Play Feature Delivery.
-
Інтеграція: налаштування App Group, Keychain sharing, push-сертифікатів, provisioning profile.
-
Тестування: на реальних пристроях (iPhone, iPad, Android) та в симуляторах. Для Live Activities — тест через
xcrun simctl push.
-
Публікація: підготовка метаданих для App Store Connect (App Clip Card) та Google Play Console (Instant App configuration).
-
Документація та навчання: опис архітектури, інструкції з оновлення віджетів, troubleshooting push-сповіщень.
Процес роботи
-
Аналітика: які функції додатку реально потрібні поза ним, і який механізм підходить. Віджет з прогнозом — WidgetKit. Трекінг доставки — Live Activity. Оплата на касі — App Clip.
-
Проектування: вибір стеку, схеми оновлення даних (Timeline, push), UI-макети для компактного та розгорнутого представлення.
-
Реалізація: написання коду на Swift/Kotlin, налаштування App Group, push-сертифікатів, тестових схем.
-
Тест: кожне розширення тестується ізольовано. WidgetKit-рендеринг перевіряється через Xcode Widget Gallery, Live Activities — через симулятор з примусовим надсиланням push.
-
Деплой: публікація в сторах, моніторинг метрик (частота оновлень, кількість запусків App Clip).
Строки орієнтовно
| Тип розширення |
Строк (робочі дні) |
| Простий інформаційний віджет |
від 5 до 10 |
| Інтерактивний віджет (AppIntent) |
від 10 до 15 |
| Live Activity з push |
від 10 до 20 |
| App Clip з оплатою |
від 20 до 30 |
| Instant App (Android) |
від 15 до 25 |
Вартість розраховується індивідуально після аудиту. Оцінка надається протягом 2 робочих днів.
Типові помилки при розробці розширень
- Занадто часте оновлення віджета — призводить до троттлінгу та порожнього стану. Рекомендуємо інтервал не менше 15 хвилин (див. Apple Human Interface Guidelines, WidgetKit documentation).
- Ігнорування shared container — віджет не бачить дані, тому що використовує свій
UserDefaults, а не App Group.
- Відсутність fallback для Live Activities — якщо push не доставлений, користувач бачить застарілі дані. Потрібен механізм періодичного опитування через
Activity.update з pushType: nil.
- Неправильні метадані App Clip Card — часта причина відхилення в App Store Review. Наприклад, некоректний URL або відсутній значок.
Зв'яжіться з нами, щоб оцінити, яке розширення підходить вашому додатку. Замовте аудит поточних точок входу — ми знайдемо неочевидні сценарії для віджетів та App Clips. Отримайте консультацію інженера з архітектури вже сьогодні. Гарантуємо проходження App Store Review з першого разу — наш досвід підтверджений десятками успішних публікацій.