Реалізація синхронізації даних між iPhone та Apple Watch
Синхронізація між iPhone та Apple Watch — окрема дисципліна з набором обмежень, які сильно відрізняються від звичайної мережевої роботи. Watch працює на watchOS і спілкується з iPhone через WatchConnectivity. Без розуміння режимів передачі та життєвого циклу Watch-програми отримуємо або втрати даних, або розряджену батарею.
WatchConnectivity: три канали передачі
WCSession надає кілька механізмів, кожен для своєї задачі:
updateApplicationContext — словник, який система доставляє при наступній активації Watch-програми. Новий виклик перезаписує попередній. Підходить для «останнього актуального стану»: налаштування програми, профіль користувача. Не підходить для черги подій — проміжні значення втрачаються.
sendMessage — синхронна передача в реальному часі, працює тільки коли обидві програми активні. Якщо Watch-програма у фоні — повідомлення дропується. Відповідь через replyHandler. Використовується для команд: користувач натиснув кнопку на Watch, iPhone повинен відповісти негайно.
transferUserInfo — черга, яка гарантує доставку навіть якщо Watch-програма закрита. Кожен виклик ставиться в чергу окремо, нічого не перезаписується. Підходить для тренувань, кроків, подій — усього, що важливо не втратити.
transferFile — передача файлів (зображення, аудіо, бази даних). Також ставиться в чергу, доставляється у фоні.
import WatchConnectivity
class WatchSessionManager: NSObject, WCSessionDelegate {
private let session = WCSession.default
func setup() {
guard WCSession.isSupported() else { return }
session.delegate = self
session.activate()
}
// Отправка актуальних даних (налаштування):
func syncSettings(_ settings: [String: Any]) {
guard session.isReachable else {
// Watch не доступен зараз — використовуємо applicationContext для відкладеної доставки
try? session.updateApplicationContext(settings)
return
}
session.sendMessage(settings, replyHandler: nil)
}
// Отправка подій з черги (тренування, трансакція):
func enqueueWorkout(_ workout: WorkoutData) {
session.transferUserInfo(workout.dictionary)
}
}
Життєвий цикл та типові помилки
Watch-програма не живе постійно у фоні. Вона має суворий бюджет: якщо програма не активувалася давно, watchOS її вивантажить. При наступному відкритті — applicationContext прийде, sendMessage-повідомлення — ні.
Найчастіша помилка: розробник використовує sendMessage для доставки даних за останні 8 годин (наприклад, кроки з HealthKit) і дивується, чому дані втрачаються. sendMessage — тільки для real-time, коли обидва пристрої активні. Для даних «доставити при наступному відкритті» — transferUserInfo.
WCSession.delegate повинен бути встановлений до activate(). Встановлення після — не викликає крах, але гарантовано пропускає перші подіі. У SwiftUI-проекті створіть WatchSessionManager в @main App до появи першого View.
Обробка на Watch-стороні
// WKExtensionDelegate або watchOS App lifecycle
func session(_ session: WCSession,
didReceiveApplicationContext applicationContext: [String: Any]) {
DispatchQueue.main.async {
// оновлюємо UI лише на main queue
self.viewModel.updateFromContext(applicationContext)
}
}
func session(_ session: WCSession,
didReceiveUserInfo userInfo: [String: Any]) {
// зберігаємо дані в локальне сховище Watch
WorkoutStore.shared.save(userInfo)
}
Обробники WCSession викликаються на background queue. Будь-яке оновлення UI повинно бути через DispatchQueue.main.async — це не опціонально.
Коли WatchConnectivity недостатньо
Якщо потрібна синхронізація даних без активного з'єднання з iPhone — CloudKit або Core Data з cloud sync. Watch має власний CloudKit-контейнер і може синхронізуватися безпосередньо з сервером, мінуючи iPhone. Це важливо для сценаріїв, коли Watch працює без iPhone (тренування в басейні, пробіжка без телефону).
HealthKit — окрема історія: дані про тренування, пульс, кроки зберігаються в спільному HealthKit-сховищі і доступні як на iPhone, так і на Watch через однаковий HKHealthStore API. WatchConnectivity для HealthKit-даних використовувати не потрібно.
Що входить до роботи
- Налаштування
WCSessionна обох сторонах з правильним життєвим циклом - Вибір механізму передачі для кожного типу даних
- Черга
transferUserInfoдля гарантованої доставки - Обробка помилок та перевірка станів:
isReachable,isPaired,isWatchAppInstalled - Тестування на фізичному iPhone + Apple Watch (симулятор WatchConnectivity обмежений)
- Синхронізація через CloudKit при необхідності автономної роботи Watch
Терміни
3–5 днів залежно від складності синхронізуємих даних та вимог до offline-режиму. Вартість розраховується індивідуально після аналізу архітектури проекту.







