我曾经使用以下语句将重要的应用程序数据(例如登录凭据)保存到 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))
}
}
}
}
有用的链接:
关于ios - SwiftUI:什么是@AppStorage 属性包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62562534/