ios - SwiftUI:什么是@AppStorage 属性包装器

标签 ios swift swiftui userdefaults ios14

我曾经使用以下语句将重要的应用程序数据(例如登录凭据)保存到 UserDefaults 中:

UserDefaults.standard.set("sample@email.com", forKey: "emailAddress")
现在,我知道 SwiftUI 引入了新的属性包装器,称为:

@AppStorage


谁能解释一下新功能是如何工作的?

最佳答案

应用存储@AppStorage是一种从 UserDefaults 保存和读取变量的便捷方式,并以与 @State 相同的方式使用它们特性。可以看成是@State自动保存到(和读取)UserDefaults 的属性.
你可以想到以下几点:

@AppStorage("emailAddress") var emailAddress: String = "sample@email.com"
作为这个的等价物(这在 SwiftUI 中是不允许的,并且不会编译):
@State var emailAddress: String = "sample@email.com" {
    get {
        UserDefaults.standard.string(forKey: "emailAddress")
    }
    set {
        UserDefaults.standard.set(newValue, forKey: "emailAddress")
    }
}
请注意 @AppStorage行为类似于 @State :对其值的更改将使 View 无效并重绘。
默认 @AppStorage将使用 UserDefaults.standard .但是,您可以指定自己的 UserDefaults店铺:
@AppStorage("emailAddress", store: UserDefaults(...)) ...

不支持的类型(例如 Array ):
如 iOSDevil 的 answer 中所述, AppStorage目前用途有限:

types you can use in @AppStorage are (currently) limited to: Bool, Int, Double, String, URL, Data


如果您想使用任何其他类型(如 Array ),您可以添加与 RawRepresentable 的一致性:
extension Array: RawRepresentable where Element: Codable {
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8),
              let result = try? JSONDecoder().decode([Element].self, from: data)
        else {
            return nil
        }
        self = result
    }

    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
              let result = String(data: data, encoding: .utf8)
        else {
            return "[]"
        }
        return result
    }
}
演示:
struct ContentView: View {
    @AppStorage("itemsInt") var itemsInt = [1, 2, 3]
    @AppStorage("itemsBool") var itemsBool = [true, false, true]

    var body: some View {
        VStack {
            Text("itemsInt: \(String(describing: itemsInt))")
            Text("itemsBool: \(String(describing: itemsBool))")
            Button("Add item") {
                itemsInt.append(Int.random(in: 1...10))
                itemsBool.append(Int.random(in: 1...10).isMultiple(of: 2))
            }
        }
    }
}

有用的链接:
  • What is the @AppStorage property wrapper?
  • AppStorage Property Wrapper SwiftUI
  • 关于ios - SwiftUI:什么是@AppStorage 属性包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62562534/

    相关文章:

    ios - 关闭UIButton闪烁动画

    ios - 唯一标识符的图像缓存最佳实践

    点击另一个 TextField 时,SwiftUI TextField 不会提交更改

    ios - SwiftUI 列表中所有行的高度相同

    SwiftUI TapGesture onStart/TouchDown

    jquery - 在 :fixed tablets only 位置发出

    ios - 如何使用 Swift 在 Firebase 数据库中设置多个值?

    ios - 使用自动布局将 float View 置于第二行

    ios - Swift 协变泛型

    ios - 核心数据: Get Records where more than one objects available in relationship