UserDefaults 一般用于小数据的持久性存储,当 App 启动时,系统会自动加载 UserDefaults 中的数据,如果存太多数据到 UserDefaults 中,那么 App 的启动有可能会变慢。最多不要超过512KB 的数据。
UserDefaults 的使用很简单,一个是取,一个是存,但是 UserDefaults 不会马上存储值,iOS 系统认为用户可能会来来回回多次切换启动,所以 iOS 会在某些时刻将这些改变一次性写入保存。如果需要马上存储值需要手动调用同步。
UserDefaults 写入用 set()
方法,可以指定写入的数据类型,也可以不指定,Swift 推断
UserDefaults.standard.set(number, forKey: "number")
UserDefaults 读取用 KVC 的键值读取,可以指定数据类型读取
UserDefaults.standard.integer(forKey: "number")
常规我们使用 UserDefaults 一般是这么配套使用
struct ContentView: View {
@State private var number = UserDefaults.standard.integer(forKey: "number")
var body: some View {
Text("(number)")
Button("增加"){
number += 1
UserDefaults.standard.set(number, forKey: "number")
UserDefaults.standard.synchronize()
}
}
}
但是这种传统的使用方式,没有默认值,比如 读取 Boolean 值,当通过 UserDefaults 读取的 key 不存在时会返回 false ,但是这个 false 是真的我们真正业务逻辑上的 false 吗?
在 SwiftUI 中 ,提供了更为简单的用法,SwiftUI 提供了一个 @AppStorage
的属性包装器,可以简化对 UserDefaults 的使用
struct ContentView: View {
@AppStorage("number") var number = 0
var body: some View {
Text("(number)")
Button("增加"){
number += 1
}
}
}
UserDefaults 通过 @AppStorage
属性包装器访问,这个包装器也有 @State
一样的功能, 当值发生改变时,它会根据新值重新更新 UI。括号中的字符串其实就是 UserDefaults 存储的 key ,它不必和属性取名相同,可以是任何字符串。
通过 @AppStorage
属性包装器使用 UserDefaults 还可以提供默认值,杜绝传统用法中的情况。
@AppStorage
不能处理复杂数据类型的存储(如 自定义的Swift 结构体),这可能就是 UserDefaults 不建议存储太多数据的一个提醒。如果要存储复杂数据类型,还是要直接使用 UserDefaults
UserDefaults存储自定义类型数据
UserDefaults 存储自定义类型数据需要遵循 Codable
协议,如果自定义类型中的属性都遵循 Codable
协议,那么自定义类型只需要遵循协议即可,系统会自动处理归档和解归档的相关代码。
将自定义类型数据存储在 UserDefaults 中需要使用 JSONEncoder
将其转成 Data
类型。
从 UserDefaults 取出自定义类型数据 则需要将 Data
使用 JSONDecoder
转成自定义类型。
如存储自定义类型数据
struct User: Codable {
var name: String
var age: String
}
保存自定义类型数据
struct ContentView: View {
@State private var user = User(name: "CK", age: "18")
var body: some View {
Text("(user.name) --- (user.age)")
Button("保存"){
let jsonEncoder = JSONEncoder()
if let data = try? jsonEncoder.encode(user) {
UserDefaults.standard.set(data, forKey: "user")
UserDefaults.standard.synchronize()
}
}
}
}
取出自定义类型数据
struct ContentView: View {
@State private var user = User(name: "CK", age: "18")
@State private var currentUser: User?
var body: some View {
Text("(user.name) --- (user.age)")
Button("保存"){
let jsonEncoder = JSONEncoder()
if let data = try? jsonEncoder.encode(user) {
UserDefaults.standard.set(data, forKey: "user")
UserDefaults.standard.synchronize()
}
}
Button("取出") {
let jsonDecoder = JSONDecoder()
let data = UserDefaults.standard.data(forKey: "user")
guard let data = data else { return }
if let user = try? jsonDecoder.decode(User.self, from: data) {
currentUser = user
}
}
if let user = currentUser {
Text("显示取出的数据: (user.name) --- (user.age)")
}
}
}
原文始发于微信公众号(三万之一):SwiftUI 中的@AppStorage 和 UserDefaults
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/231275.html