Реализация синхронизации данных между 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на обеих сторонах с правильным lifecycle - Выбор механизма передачи для каждого типа данных
- Очередь
transferUserInfoдля гарантированной доставки - Обработка ошибок и состояний
isReachable,isPaired,isWatchAppInstalled - Тестирование на физическом iPhone + Apple Watch (симулятор WatchConnectivity ограничен)
- Синхронизация через CloudKit при необходимости автономной работы Watch
Сроки
3–5 дней в зависимости от сложности синхронизируемых данных и требований к offline-режиму. Стоимость рассчитывается индивидуально после анализа архитектуры проекта.







