在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/