返回

用 SwiftUI 的 @AppStorage 优雅高效地存储用户数据

IOS

导言

SwiftUI 中的 @AppStorage 是一个强大的工具,可用于在应用程序的整个生命周期中持久存储用户数据。然而,默认情况下,使用 @AppStorage 可能会很麻烦,特别是当需要处理复杂数据类型或需要在多个视图中访问数据时。

本指南将深入探讨如何优雅、高效和安全地使用 @AppStorage,同时解决当前使用中出现的痛点,让你在 SwiftUI 中自信地管理用户数据。

使用 @AppStorage 的痛点

以下是使用 @AppStorage 时常见的痛点:

  • 处理复杂数据类型: @AppStorage 仅限于存储基础数据类型,如字符串、整数和布尔值。存储复杂对象,例如自定义结构体或类,需要额外的编码和解码步骤。
  • 在多个视图中访问数据: 在多个视图中共享 @AppStorage 数据需要使用环境对象,这可能会导致复杂且难以维护的代码。
  • 确保数据安全: 在设备上存储敏感数据时,需要采取安全措施来保护数据免遭未经授权的访问。

优雅而高效地使用 @AppStorage

为了解决这些痛点,我们可以采用以下策略:

1. 使用 Codable 协议处理复杂数据类型:

使用 Codable 协议可以轻松地将自定义对象编码为 JSON 数据,然后将其存储在 @AppStorage 中。这样可以避免额外的编码和解码工作。

struct UserSettings: Codable {
    var username: String
    var theme: String
}

@AppStorage("userSettings") var userSettings: UserSettings?

2. 创建一个自定义 @AppStorage 存储属性包装器:

创建自定义存储属性包装器可以简化在多个视图中访问 @AppStorage 数据的过程。它还允许我们添加自定义逻辑和安全措施。

@propertyWrapper
struct AppStorageWrapper<T: Codable> {
    private let key: String
    private var defaultValue: T

    init(key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            // 从 @AppStorage 中获取数据,如果不存在,则返回默认值
            UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            // 将数据存储到 @AppStorage
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

3. 使用 iCloud 同步确保数据安全:

iCloud 同步可以确保 @AppStorage 中的数据在用户的所有设备上保持同步。它还提供了一个额外的安全层,因为数据存储在 Apple 的安全服务器上。

@AppStorage("userSettings") var userSettings: UserSettings? {
    didSet {
        // iCloud 同步数据
        NSUbiquitousKeyValueStore.default.set(userSettings, forKey: "userSettings")
    }
}

结论

通过采用这些策略,我们可以充分利用 @AppStorage 的强大功能,同时解决使用中的痛点。这使我们能够优雅、高效和安全地存储用户数据,为 SwiftUI 应用程序提供更无缝的用户体验。