SwiftUI字段同步到iCloud
SwiftUI字段同步到iCloud

SwiftUI字段同步到iCloud

在SwiftUI中,通常使用 @AppStorage保存字段,但是@AppStorage仅能将字段数据保存到设备本地。

因此,需要使用使用 NSUbiquitousKeyValueStore 将数据同步到iCloud。

配置 iCloud

首先,确保在 Xcode 项目中启用了 iCloud 并配置了 iCloud 容器。

打开 Xcode 项目。

转到 Signing & Capabilities 选项卡。

启用 iCloud,确保勾选了 iCloud Key-Value Store。

如果之前没有接触过iCloud,相关教程可以查看《SwiftData数据同步到iCloud

使用 NSUbiquitousKeyValueStore 实现同步

NSUbiquitousKeyValueStore 可以在不同设备之间同步数据。需要手动同步 CurrencySymbol。

1、上传字段数据到iCloud

let store = NSUbiquitousKeyValueStore.default
store.set(CurrencySymbol, forKey: "CurrencySymbol")
store.synchronize()

这段代码表示,创建CurrencySymbol变量的键值对。

键为“CurrencySymbol”,值为CurrencySymbol变量。

使用NSUbiquitousKeyValueStore,将键值对同步到iCloud。

2、从iCloud获取键值对

// 从 iCloud 加载 CurrencySymbol 的值
let store = NSUbiquitousKeyValueStore.default
if let storedSymbol = store.string(forKey: "CurrencySymbol"), storedSymbol != "" {
    // 只有当 iCloud 存储值非空时才覆盖本地值
    CurrencySymbol = storedSymbol
}

这段代码表示,尝试获取键为“CurrencySymbol”的值,如果获取的值不为空,进行赋值操作。

3、@AppStorage同步iCloud

@AppStorage("CurrencySymbol") var CurrencySymbol: String = "USD" {
    didSet {
        // 每次 CurrencySymbol 更新时,同步到 iCloud
           let store = NSUbiquitousKeyValueStore.default
           store.set(CurrencySymbol, forKey: "CurrencySymbol")
        store.synchronize()
    }
}

可以将前面的键值对同步iCloud方法,汇总到@AppStorage包装器中。

当修改CurrencySymbol变量时,会同步修改iCloud的变量。

读取不同的字段类型

在store中读取Int、Double的格式也有所区别:

// 读取整数值
if let storedPageSteps = store.object(forKey: "pageSteps") as? Int {
    pageSteps = storedPageSteps
}
// 读取双精度值
if store.object(forKey: "reminderTime") != nil {
    reminderTime = store.double(forKey: "reminderTime")
}
// 读取布尔值
if store.object(forKey: "isBiometricEnabled") != nil {
    isBiometricEnabled = store.bool(forKey: "isBiometricEnabled")
}
// 读取字符串值
if let storedBackgroundImage = store.string(forKey: "BackgroundImage") {
    BackgroundImage = storedBackgroundImage
}

因此,需要根据数据类型进度读取。

注意事项

NSUbiquitousKeyValueStore 会在设备之间同步数据,但同步不是即时的。可以使用 synchronize() 强制同步,但 iCloud 同步可能会有延迟。

确保 CurrencySymbol 是一个基本类型(如字符串、整数、布尔值等),因为 NSUbiquitousKeyValueStore 仅支持这些类型。

总结

通过NSUbiquitousKeyValueStore,可以实现iCloud的字段同步功能。

iCloud存储的字段数据在iOS、iPadOS和macOS等多平台共享,因此如果修改一端,其他设备需要立即同步数据,可以通过NotificationCenter监听实现。

在实际应用中,同步字段通常用于配置文件等场景,因此推荐使用单例类管理数据的变化,相关案例请见GitHub的“存钱猪猪”管理类

使用NotificationCenter监听iCloud数据变化

还可以通过NotificationCenter进一步监听iCloud数据变化和应用生命周期变化,从而实现数据的同步。

/// 监听 iCloud 变化,同步到本地
private func observeiCloudChanges() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(iCloudDidUpdate),
        name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
        object: NSUbiquitousKeyValueStore.default
    )
}

/// iCloud 数据变化时,更新本地数据
@objc private func iCloudDidUpdate(notification: Notification) {
    print("iCloud数据发生变化,更新本地数据")
    DispatchQueue.main.async {
        self.loadFromiCloud()
    }
}

/// 监听应用生命周期事件
private func observeAppLifecycle() {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(appWillResignActive),
        name: UIApplication.willResignActiveNotification,
        object: nil
    )
}

/// 当应用进入后台时,将数据同步到 iCloud
@objc private func appWillResignActive() {
    print("应用进入后台,将本地数据同步到iCloud")
    syncToiCloud()
}

/// 防止内存泄漏
deinit {
    NotificationCenter.default.removeObserver(self, name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, object: NSUbiquitousKeyValueStore.default)
    NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
}

相关文章

1、SwiftData数据同步到iCloud:https://fangjunyu.com/2024/11/10/swiftdata%e6%95%b0%e6%8d%ae%e5%90%8c%e6%ad%a5%e5%88%b0icloud/

2、iOS通知机制NotificationCenter:https://fangjunyu.com/2025/03/01/ios%e9%80%9a%e7%9f%a5%e6%9c%ba%e5%88%b6notificationcenter/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注