Розробка Apple Watch додатку (watchOS)
Клієнт замовив трекер тренувань для Apple Watch із синхронізацією даних на iPhone. Перша версія втрачала до 5% записів через те, що WCSession.sendMessage працював лише при активному додатку, а WKExtendedRuntimeSession не був налаштований. Ми перепроектували архітектуру: використали HKWorkoutSession для необмеженого фону та transferUserInfo для гарантованої доставки. Втрати даних скоротилися до 0.01%. Зараз додаток обробляє до 1000 тренувань на день без збоїв.
watchOS-додаток — це окремий таргет зі своїм життєвим циклом, обмеженими ресурсами (512 МБ RAM на Series 4, 1 ГБ на Series 9) та специфічними паттернами. Ми використовуємо SwiftUI, Combine та async/await для реактивної архітектури. Середній час розробки — 2–4 тижні для комплексного рішення. При налаштуванні code signing для watchOS потрібні окремі provisioning profiles — це часта помилка у початківців. Ми наполегливо рекомендуємо тестувати complications на реальних годинниках, оскільки симулятор не відображає справжню продуктивність та обмеження енергоспоживання.
В основі кожного проекту лежить глибокий аналіз сценаріїв використання: чи буде Watch працювати автономно або як companion-додаток? Від цього залежить вибір механізму синхронізації. Серед наших проектів — додатки для фітнесу, медитації та розумного дому, кожен з унікальною архітектурою. Ми спеціалізуємося на watchOS більше 5 років і випустили 20+ додатків у App Store. Замовте розробку watchOS додатку під ключ — від ідеї до публікації в App Store.
Як гарантувати доставку даних при синхронізації?
WCSession — канал зв'язку між додатками на iPhone та Watch. Не між пристроями в цілому, а саме між додатками. Три механізми передачі даних:
| Механізм |
Коли працює |
Швидкість |
Гарантія доставки |
Типове застосування |
| sendMessage |
Обидва додатки активні |
Миттєво |
Ні (якщо Watch заснув) |
Команди, запити даних у foreground |
| updateApplicationContext |
Будь-який стан (у т.ч. фон) |
При наступному пробудженні |
Так, перезаписується |
Поточний стан (тренування, налаштування) |
| transferUserInfo |
Будь-який стан |
По порядку, із затримкою |
Так, черга |
Логи подій, транзакції |
WatchConnectivity через sendMessage у 10 разів швидше, ніж updateApplicationContext, але вимагає активного додатку. Для фонової доставки — тільки updateApplicationContext або transferUserInfo.
WCSession.default.sendMessage(["action": "fetchData"], replyHandler: { reply in
// Відповідь від iPhone
}, errorHandler: { error in
// Обробка помилки (Watch недоступний)
})
try WCSession.default.updateApplicationContext(["lastSync": Date().timeIntervalSince1970])
Якщо додаток активний на обох пристроях — використовуйте sendMessage для негайної відповіді. Для фонової синхронізації стану (наприклад, поточні показники тренування) — updateApplicationContext. Для черги подій — transferUserInfo. Перевірка WCSession.default.isReachable асинхронна: завжди обробляйте errorHandler.
Чому complications розряджають батарею?
Часта помилка — часто оновлювати timeline або запитувати дані з мережі. Оптимальне рішення: оновлювати timeline раз на годину, використовувати HealthKit для локальних даних. Для економії заряду слідуйте рекомендаціям Apple щодо обмеження частоти оновлення.
Complications — елементи на циферблаті годинника. З ClockKit (застарілий) → тепер WidgetKit, аналогічний iOS. ComplicationConfiguration через WidgetConfiguration — той же API, що й iOS віджети. Сімейства: .circularSmall, .modularSmall, .modularLarge, .utilitarianSmall, .utilitarianLarge, .graphicCorner, .graphicBezel, .graphicCircular, .graphicRectangular, .graphicExtraLarge. Timeline у Complication працює як iOS WidgetKit: TimelineProvider, заздалегідь заповнені TimelineEntry. Годинник знає, що показати на наступні кілька годин — економія батареї. CLKComplicationDataSource.getPrivacyBehavior — що показувати на заблокованому циферблаті. hideOnLockScreen — приховати дані, показати пусту комплекцію.
Background Modes на watchOS
WKExtendedRuntimeSession — до 60 хвилин фонової роботи для специфічних сценаріїв:
-
workout — тренування (необмежений час з активним WorkoutSession)
-
selfCare — медитація, дихальні вправи (до 10 хвилин після екрану)
-
alarm — будильник (вимагає дозволу користувача)
-
sleepTracking — відстеження сну (ніч)
Для трекінгу тренування: HKWorkoutSession + HKLiveWorkoutBuilder — офіційний API. Без HKWorkoutSession система агресивно вбиває фонові процеси. Мережеві запити у фоні через URLSession з фоновою конфігурацією не підтримуються — дані тільки через iPhone (WatchConnectivity) або при наступному foreground-запуску.
Технічна деталь: налаштування WKExtendedRuntimeSession
Для запуску необхідно викликати start() та вказати тип. Важливо: сесія вимагає явного invalidate() після завершення, інакше працюватиме до таймауту. Приклад:
let session = WKExtendedRuntimeSession()
session.start(with: .workout)
// ...
session.invalidate()
UX-особливості
Екран маленький: Series 4+ — 44mm (368×448pt retina). Мінімальний touch target — 44pt. Список рядків без складної ієрархії — найкраща навігація. Digital Crown — прокрутка контенту, zoom у MapKit, введення значень через Stepper або Picker з кастомним стилем. onLongPressGesture — працює, але вимагає 0.8 секунд за замовчуванням — часто випадкові спрацьовування. Haptic feedback через WKInterfaceDevice.current().play(.click) — важливий UX-елемент, де візуальні відповіді обмежені.
Що входить у розробку watchOS-додатку
- Проектування архітектури: Shared код з iOS, виділений watchOS-таргет.
- Налаштування WatchConnectivity: вибір механізму під ваш сценарій.
- Реалізація complications: підтримка 5+ сімейств, налаштування timeline.
- Інтеграція HealthKit / CoreMotion / інших датчиків.
- Тестування на реальних пристроях (Series 4, Series 9, Ultra).
- Підготовка для App Store: provisioning profiles, code signing, іконки.
- Документація з синхронізації та фонових завдань.
- Гарантійна підтримка 1 місяць після публікації.
Терміни та вартість
Повноцінний watchOS-додаток з WatchConnectivity та complications — 1–2 тижні. Простий companion-app (без власної логіки) — 3–5 днів. Вартість розраховується після аналізу вимог. Замовте безкоштовну консультацію — оцінимо проект. Зв'яжіться з нами для деталей.
Ми займаємося мобільною розробкою більше 5 років, випустили понад 20 додатків у App Store. Наші рішення працюють стабільно — гарантуємо дотримання App Store Review Guidelines та рекомендацій щодо продуктивності.
Отримайте консультацію інженера — це безкоштовно. Зв'яжіться з нами для детальної оцінки вашого проекту.
Розробка віджетів, 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 з першого разу — наш досвід підтверджений десятками успішних публікацій.