应用存储
@AppStorage
是一种从 UserDefaults 保存和读取变量并以与@State
特性。它可以被看作是一个@State
自动保存(和读取)的属性UserDefaults
.
你可以考虑以下几点:
@AppStorage("emailAddress") var emailAddress: String = "[email protected] /cdn-cgi/l/email-protection"
相当于这个(即notSwiftUI 中允许并且将not编译):
@State var emailAddress: String = "[email protected] /cdn-cgi/l/email-protection" {
get {
UserDefaults.standard.string(forKey: "emailAddress")
}
set {
UserDefaults.standard.set(newValue, forKey: "emailAddress")
}
}
注意@AppStorage
行为就像@State
:对其值的更改将使视图无效并重新绘制。
默认情况下@AppStorage
将使用UserDefaults.standard
。但是,您可以指定自己的UserDefaults
store:
@AppStorage("emailAddress", store: UserDefaults(...)) ...
不支持的类型(例如,Array
):
正如 iOSDevil 中提到的answer https://stackoverflow.com/a/62849282/8697793, AppStorage
目前用途有限:
您可以在 @AppStorage 中使用的类型(当前)仅限于: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
}
}
Demo:
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))
}
}
}
}
有用的链接:
- 什么是 @AppStorage 属性包装器? https://www.hackingwithswift.com/quick-start/swiftui/what-is-the-appstorage-property-wrapper
- AppStorage 属性包装器 SwiftUI https://medium.com/@ruchish7187/appstorage-property-wrapper-swiftui-c4ceba7ff5e7