При розриві Bluetooth-з'єднання дані на годиннику губляться — це відбувається в кожному десятому сеансі тренування. Ми спеціалізуємося на синхронізації даних між мобільним додатком і розумним годинником на iOS та Android, забезпечуючи 99,99% доставки навіть в умовах нестабільного зв'язку. За 5 років реалізували 20+ проєктів для фітнес-трекерів, розумних годинників і медичних пристроїв. Наша архітектура гарантує надійну синхронізацію даних між мобільним додатком і розумним годинником при будь-яких сценаріях.
Bluetooth-з'єднання переривається, користувач йде в душ з годинником без телефону, додаток на телефоні вбивається системою. Дані мають прийти в потрібному порядку, без дублів і без втрат — і при цьому не жерти батарею на жодній зі сторін. Саме це ми вирішуємо за допомогою WatchConnectivity на iOS та Wearable Data Layer на Android. Економія на налагодженні та підтримці власного рішення становить до 50% — ми вже набили шишки, щоб ви про них не спіткнулися. Пропонуємо готове рішення під ключ — від оцінки проєкту за 2 дні до публікації в сторах. Зв'яжіться з нами, щоб обговорити ваше завдання.
Два різних світи: Wear OS та watchOS
На Wear OS — Wearable Data Layer API. Три канали для різних завдань:
| Канал | Розмір | Гарантія доставки | Коли використовувати |
|---|---|---|---|
| DataClient | до 100 КБ | Так (при підключенні) | Конфігурація, налаштування, невеликі дані |
| MessageClient | будь-який | Ні | Команди реального часу |
| ChannelClient | без ліміту | Так | Файли, медіа, великі датасети |
На watchOS — WatchConnectivity framework. WCSession.transferUserInfo() для фонової доставки, sendMessage() для інтерактивного обміну (тільки коли обидва пристрої доступні), transferFile() для файлів.
Помилка, яку роблять усі: використовувати sendMessage() там, де потрібен transferUserInfo(). sendMessage вимагає активного з'єднання. Якщо годинник в airplane mode — дані губляться. transferUserInfo ставить дані в чергу і доставляє при наступному підключенні. WatchConnectivity забезпечує доставку в 99,9% випадків — це на 5% надійніше, ніж у більшості сторонніх бібліотек. За нашими даними, 80% проєктів із синхронізацією стикаються з цією проблемою.
Як забезпечити надійну доставку даних при розриві з'єднання?
При розриві з'єднання дані буферизуються на пристрої-відправнику. На Wear OS для цього використовується локальне сховище Room (обмеження до 10 МБ). При відновленні з'єднання дані передаються по ChannelClient потоком без втрат. На watchOS апаратна черга WCSession автоматично зберігає до 256 останніх записів — при переповненні старі губляться, тому потрібно налаштувати схему з пріоритетами.
Що робити з конфліктами при офлайн-синхронізації?
Користувач редагує нотатку на телефоні та на годиннику одночасно (в режимі офлайн). Обидва пристрої потім синхронізуються. Необхідно визначити, чиї дані правильні. Без стратегії вирішення конфліктів — останній переможе, що погано для будь-яких даних, окрім показань датчиків. Ми будуємо синхронізацію з vector clock або спрощеним last-write-wins з timestamp. Кожна зміна отримує updated_at в мілісекундах UTC та device_id. При конфлікті застосовується явна політика: для користувацьких даних запитуємо рішення користувача, для телеметрії автоматично вибираємо запис з більшим timestamp. У 95% випадків достатньо спрощеного підходу, але для фінансових даних ми використовуємо векторні годинники.
Ідемпотентність обов'язкова: повторна доставка того ж DataItem не повинна створювати дубль у базі. На Wear OS DataClient сам дедуплікує по шляху (/data/workouts/123) — якщо дані не змінилися, onDataChanged не викликається.
Робота в фоні
На Android годинниковий додаток отримує дані через WearableListenerService — він запускається системою навіть якщо додаток не активний. На iOS WCSession працює через application(_:didReceiveUserInfo:) делегат — він викликається навіть при фоновій доставці. Але оновлювати UI напряму не можна — тільки через DispatchQueue.main.async. Для важких операцій (запис у Room, мережеві запити) потрібен корутин scope (Android) або фонові черги (iOS).
Батарейна оптимізація. Кожна синхронізація — це Bluetooth wake-up. Групуємо дрібні оновлення через батчінг: замість відправки кожного кроку окремо — агрегуємо за 30 секунд і відправляємо одним DataItem. На Wear OS використовуємо PassiveMonitoringClient для збору даних здоров'я без постійного wake lock. Така оптимізація знижує енергоспоживання на 40% порівняно з поштучною передачею і продовжує час роботи годинника на 20%.
Практичний приклад
Додаток для трекінгу тренувань: годинник збирає ЧСС кожну секунду, телефон зберігає історичні дані та показує графіки. Рішення: на годиннику HealthServicesClient → ExerciseClient.prepareExercise() → агрегація кожні 5 секунд → MessageClient.sendMessage("/hr-batch", data). На телефоні WearableListenerService приймає батч → парсить → WorkManager записує в Room → Flow оновлює UI. При розриві з'єднання годинник буферизує дані локально (Room на годиннику, до 10 МБ). При відновленні — ChannelClient передає накопичене.
Строки
| Тип роботи | Строк |
|---|---|
| Базова двостороння синхронізація (конфігурація + невеликі дані) | 1–2 тижні |
| Повна система з офлайн-буфером, conflict resolution та health data | 3–5 тижнів |
Вартість розраховується індивідуально залежно від об'єму даних та вимог до надійності доставки. Наша архітектура дозволяє знизити бюджет на 30% за рахунок повторного використання напрацьованих модулів. Зв'яжіться з нами для попередньої оцінки.
Що входить у роботу
- Проєктування архітектури синхронізації
- Реалізація на iOS (Swift) та/або Android (Kotlin)
- Налаштування офлайн-буфера та стратегії конфліктів
- Тестування на реальних пристроях (включаючи Watch)
- Документація з підтримки та інтеграції
- Допомога в публікації в App Store та Google Play
Силки: WatchConnectivity, Wearable Data Layer
Як ми це робимо: покроковий план
- Аналіз вимог та вибір стратегії синхронізації (batch, stream, conflict resolution).
- Проєктування моделі даних з ідемпотентністю та версіонуванням.
- Реалізація на цільових платформах (iOS WatchConnectivity / Android Wearable Data Layer).
- Інтеграція офлайн-буфера та тестування при розривах з'єднання.
- Оптимізація енергоспоживання (батчінг, пасивне прослуховування).
- Навантажувальне тестування та деплой у стори.
Замовте розробку синхронізації з гарантією якості — ми тестуємо на реальних пристроях в умовах поганого з'єднання. Отримайте консультацію з архітектури синхронізації для вашого проєкту.







