SwiftUI:什么是@AppStorage 属性包装器 [英] SwiftUI: What is @AppStorage property wrapper
问题描述
我曾经使用以下语句将重要的应用程序数据(例如登录凭据)保存到 UserDefaults 中:
I used to save important App data like login credentials into UserDefaults using the following statement:
UserDefaults.standard.set("sample@email.com", forKey: "emailAddress")
现在,我知道 SwiftUI 引入了新的属性包装器,名为:
Now, I have come to know SwiftUI has introduced new property wrapper called:
@AppStorage
@AppStorage
谁能解释一下新功能的工作原理?
Could anyone please explain how the new feature works?
推荐答案
AppStorage
@AppStorage
是一种从 UserDefaults 保存和读取变量的便捷方式,并以与 @State
属性相同的方式使用它们.它可以看作是一个 @State
属性,它会自动保存到(并从中读取)UserDefaults
.
AppStorage
@AppStorage
is a convenient way to save and read variables from UserDefaults and use them in the same way as @State
properties. It can be seen as a @State
property which is automatically saved to (and read from) UserDefaults
.
你可以想到以下几点:
@AppStorage("emailAddress") var emailAddress: String = "sample@email.com"
与此等效(在 SwiftUI 中不允许并且不会编译):
as an equivalent of this (which is not allowed in SwiftUI and will not compile):
@State var emailAddress: String = "sample@email.com" {
get {
UserDefaults.standard.string(forKey: "emailAddress")
}
set {
UserDefaults.standard.set(newValue, forKey: "emailAddress")
}
}
请注意,@AppStorage
的行为类似于 @State
:对其值的更改将使视图无效并重绘.
Note that @AppStorage
behaves like a @State
: a change to its value will invalidate and redraw a View.
默认@AppStorage
将使用UserDefaults.standard
.但是,您可以指定自己的 UserDefaults
存储:
By default @AppStorage
will use UserDefaults.standard
. However, you can specify your own UserDefaults
store:
@AppStorage("emailAddress", store: UserDefaults(...)) ...
不支持的类型(例如,Array
):
如 iOSDevil 的 answer 中所述,AppStorage
目前使用有限:
Unsupported types (e.g., Array
):
As mentioned in iOSDevil's answer, AppStorage
is currently of limited use:
您可以在@AppStorage 中使用的类型(目前)仅限于:Bool、Int、Double、String、URL、Data
types you can use in @AppStorage are (currently) limited to: Bool, Int, Double, String, URL, Data
如果你想使用任何其他类型(比如Array
),你可以添加对RawRepresentable
的一致性:
If you want to use any other type (like Array
), you can add conformance to 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))
}
}
}
}
有用的链接:
- 什么是@AppStorage 属性包装器?
- AppStorage 属性包装器 SwiftUI
这篇关于SwiftUI:什么是@AppStorage 属性包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!