Использование SyncState

June 11, 2026 · View on GitHub

SyncState — это компонент библиотеки AppState, который позволяет синхронизировать состояние приложения на нескольких устройствах с помощью iCloud. Это особенно полезно для поддержания согласованности пользовательских настроек, параметров и других важных данных на всех устройствах.

Обзор

SyncState использует NSUbiquitousKeyValueStore iCloud для синхронизации небольших объемов данных на всех устройствах. Это делает его идеальным для синхронизации легковесного состояния приложения, такого как настройки или пользовательские параметры.

Ключевые особенности

  • Синхронизация с iCloud: автоматическая синхронизация состояния на всех устройствах, вошедших в одну и ту же учетную запись iCloud.
  • Постоянное хранилище: данные постоянно хранятся в iCloud, что означает, что они сохранятся даже при завершении или перезапуске приложения.
  • Синхронизация почти в реальном времени: изменения состояния распространяются на другие устройства почти мгновенно.

Примечание: SyncState поддерживается на watchOS 9.0 и более поздних версиях.

Пример использования

Модель данных

Предположим, у нас есть структура с именем Settings, которая соответствует Codable:

struct Settings: Codable {
    var text: String
    var isShowingSheet: Bool
    var isDarkMode: Bool
}

Определение SyncState

Вы можете определить SyncState, расширив объект Application и объявив свойства состояния, которые должны быть синхронизированы:

extension Application {
    var settings: SyncState<Settings> {
        syncState(
            initial: Settings(
                text: "Hello, World!",
                isShowingSheet: false,
                isDarkMode: false
            ),
            id: "settings"
        )
    }
}

Обработка внешних изменений

Чтобы убедиться, что приложение реагирует на внешние изменения из iCloud, переопределите функцию didChangeExternally, создав настраиваемый подкласс Application:

class CustomApplication: Application {
    override func didChangeExternally(notification: Notification) {
        super.didChangeExternally(notification: notification)

        DispatchQueue.main.async {
            self.notifyChange()
        }
    }
}

Создание представлений для изменения и синхронизации состояния

В следующем примере у нас есть два представления: ContentView и ContentViewInnerView. Эти представления совместно используют и синхронизируют состояние Settings. ContentView позволяет пользователю изменять text и переключать isDarkMode, а ContentViewInnerView отображает тот же текст и обновляет его при нажатии.

struct ContentView: View {
    @SyncState(\.settings) private var settings: Settings

    var body: some View {
        VStack {
            TextField("", text: $settings.text)

            Button(settings.isDarkMode ? "Light" : "Dark") {
                settings.isDarkMode.toggle()
            }

            Button("Show") { settings.isShowingSheet = true }
        }
        .preferredColorScheme(settings.isDarkMode ? .dark : .light)
        .sheet(isPresented: $settings.isShowingSheet, content: ContentViewInnerView.init)
    }
}

struct ContentViewInnerView: View {
    @Slice(\.settings, \.text) private var text: String

    var body: some View {
        Text("\(text)")
            .onTapGesture {
                text = Date().formatted()
            }
    }
}

Настройка приложения

Наконец, настройте приложение в структуре @main. При инициализации повысьте уровень настраиваемого приложения, включите ведение журнала и загрузите зависимость хранилища iCloud для синхронизации:

@main
struct SyncStateExampleApp: App {
    init() {
        Application
            .promote(to: CustomApplication.self)
            .logging(isEnabled: true)
            .load(dependency: \.icloudStore)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Включение хранилища ключ-значение iCloud

Чтобы включить синхронизацию iCloud, убедитесь, что вы следуете этому руководству, чтобы включить возможность хранилища ключ-значение iCloud: Начало работы с SyncState.

SyncState: примечания по хранилищу iCloud

Хотя SyncState обеспечивает простую синхронизацию, важно помнить об ограничениях NSUbiquitousKeyValueStore:

  • Ограничение хранилища: вы можете хранить до 1 МБ данных в iCloud с помощью NSUbiquitousKeyValueStore, с ограничением размера значения для каждого ключа в 1 МБ.

Вопросы миграции

При обновлении вашей модели данных важно учитывать потенциальные проблемы миграции, особенно при работе с постоянными данными с использованием StoredState, FileState или SyncState. Без надлежащей обработки миграции такие изменения, как добавление новых полей или изменение форматов данных, могут вызвать проблемы при загрузке старых данных.

Вот несколько ключевых моментов, которые следует учитывать:

  • Добавление новых необязательных полей: убедитесь, что новые поля являются необязательными или имеют значения по умолчанию для поддержания обратной совместимости.
  • Обработка изменений формата данных: если структура вашей модели изменяется, реализуйте настраиваемую логику декодирования для поддержки старых форматов.
  • Версионирование ваших моделей: используйте поле version в ваших моделях, чтобы помочь с миграцией и применить логику на основе версии данных.

Чтобы узнать больше о том, как управлять миграцией и избегать потенциальных проблем, обратитесь к Руководству по вопросам миграции.

Руководство по реализации SyncState

Для получения подробных инструкций о том, как настроить iCloud и SyncState в вашем проекте, см. Руководство по реализации SyncState.

Лучшие практики

  • Используйте для небольших, критически важных данных: SyncState идеально подходит для синхронизации небольших, важных фрагментов состояния, таких как пользовательские настройки, параметры или флаги функций.
  • Контролируйте хранилище iCloud: убедитесь, что ваше использование SyncState остается в пределах ограничений хранилища iCloud, чтобы предотвратить проблемы с синхронизацией данных.
  • Обрабатывайте внешние обновления: если вашему приложению необходимо реагировать на изменения состояния, инициированные на другом устройстве, переопределите функцию didChangeExternally, чтобы обновлять состояние приложения в режиме реального времени.

Заключение

SyncState предоставляет мощный способ синхронизации небольших объемов состояния приложения на всех устройствах через iCloud. Он идеально подходит для обеспечения согласованности пользовательских настроек и других ключевых данных на всех устройствах, вошедших в одну и ту же учетную запись iCloud. Для более сложных случаев использования изучите другие функции AppState, такие как SecureState и FileState.


Этот перевод был сгенерирован автоматически и может содержать ошибки. Если вы носитель языка, мы будем признательны за ваши исправления через Pull Request.