Sha*_*jon 23 ios swift userdefaults swiftui ios14
我曾经使用以下语句将重要的应用程序数据(如登录凭据)保存到 UserDefaults 中:
UserDefaults.standard.set("sample@email.com", forKey: "emailAddress")
Run Code Online (Sandbox Code Playgroud)
现在,我知道 SwiftUI 引入了新的属性包装器,称为:
@AppStorage
谁能解释一下新功能的工作原理?
paw*_*222 27
@AppStorage是一种从 UserDefaults 保存和读取变量并以与@State属性相同的方式使用它们的便捷方法。它可以被看作是一个@State自动保存到(和读取)的属性UserDefaults。
你可以想到以下几点:
@AppStorage("emailAddress") var emailAddress: String = "sample@email.com"
Run Code Online (Sandbox Code Playgroud)
作为这方面的一个等效(其未在SwiftUI允许和将不编译):
@State var emailAddress: String = "sample@email.com" {
get {
UserDefaults.standard.string(forKey: "emailAddress")
}
set {
UserDefaults.standard.set(newValue, forKey: "emailAddress")
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,@AppStorage其行为类似于@State:对其值的更改将使视图无效并重绘。
默认情况下@AppStorage将使用UserDefaults.standard. 但是,您可以指定自己的UserDefaults商店:
@AppStorage("emailAddress", store: UserDefaults(...)) ...
Run Code Online (Sandbox Code Playgroud)
Array):正如 iOSDevil 的回答中提到的,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
}
}
Run Code Online (Sandbox Code Playgroud)
演示:
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))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
免责声明:iOS 14 Beta 2
除了其他有用的答案之外,您可以在@AppStorage 中使用的类型(当前)仅限于:Bool、Int、Double、String、URL、Data
尝试使用其他类型(例如 Array)会导致错误:“调用初始化程序时没有完全匹配”
除了 pawello2222 的回答,这里。是对 AppStorage 的重新实现,我将其命名为UserDefaultStorage:
@propertyWrapper
struct UserDefaultStorage<T: Codable> {
private let key: String
private let defaultValue: T
private let userDefaults: UserDefaults
init(key: String, default: T, store: UserDefaults = .standard) {
self.key = key
self.defaultValue = `default`
self.userDefaults = store
}
var wrappedValue: T {
get {
guard let data = userDefaults.data(forKey: key) else {
return defaultValue
}
let value = try? JSONDecoder().decode(T.self, from: data)
return value ?? defaultValue
}
set {
let data = try? JSONEncoder().encode(newValue)
userDefaults.set(data, forKey: key)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个包装器可以存储/恢复任何类型的可编码到用户默认值中/从用户默认值中恢复。此外,它在iOS的13,它并不需要进口SwiftUI。
@UserDefaultStorage(key: "myCustomKey", default: 0)
var myValue: Int
Run Code Online (Sandbox Code Playgroud)
请注意,它不能直接用作State
| 归档时间: |
|
| 查看次数: |
7782 次 |
| 最近记录: |