在 Swift 中,UserDefaults 是一个常用的轻量级数据存储方式,用于保存用户设置或简单的数据。这些数据会保存在应用的沙盒中,并且在应用重启后仍然存在。
基础操作
1、保存数据
使用 set(_:forKey:) 方法将数据存储到 UserDefaults 中:
// 保存数据
UserDefaults.standard.set("John", forKey: "username") // 保存字符串
UserDefaults.standard.set(25, forKey: "age") // 保存整数
UserDefaults.standard.set(true, forKey: "isLoggedIn") // 保存布尔值

2、读取数据
使用 object(forKey:) 方法读取数据,或使用更具体的方法:
// 读取数据
let username = UserDefaults.standard.string(forKey: "username") // 返回 String?
let age = UserDefaults.standard.integer(forKey: "age") // 返回 Int
let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn") // 返回 Bool

注意:UserDefaults.standard在读取时,需要根据存储的类型设置后缀。
比如存储的是String类型值,读取类型为:
UserDefaults.standard.string(forKey: "username")
如果存储的是Int类型值,读取类型为:
UserDefaults.standard.integer(forKey: "age")
如果读取的类型与存储的类型不一样,就会存在无法读取的情况。
3、删除数据
可以使用 removeObject(forKey:) 删除某个键对应的数据:
UserDefaults.standard.removeObject(forKey: "username")

存储复杂数据
如果需要保存更复杂的数据(例如数组或字典),UserDefaults 也可以支持,但数据必须是 PropertyList 类型(即 String、Data、Array、Dictionary 等)。
如果需要保存Set类型,需要先转换为Array类型。
1、保存和读取数组
let colors = ["Red", "Green", "Blue"]
UserDefaults.standard.set(colors, forKey: "favoriteColors")
if let savedColors = UserDefaults.standard.array(forKey: "favoriteColors") as? [String] {
print(savedColors) // 输出 ["Red", "Green", "Blue"]
}
2、保存和读取字典
let userDetails: [String: Any] = ["name": "John", "age": 25]
UserDefaults.standard.set(userDetails, forKey: "userDetails")
if let savedDetails = UserDefaults.standard.dictionary(forKey: "userDetails") {
print(savedDetails) // 输出 ["name": "John", "age": 25]
}
注意事项
1、数据量限制
UserDefaults 适合存储小型数据。对于大量或频繁修改的数据,应考虑使用数据库(如 Core Data 或 SQLite)。
2、数据同步
如果在写入后需要立即同步数据到磁盘,可以调用 synchronize() 方法,但通常不推荐手动调用。UserDefaults 会自动处理同步。
defaults.synchronize() // 手动同步(不推荐)
3、线程安全
UserDefaults 是线程安全的,但建议在主线程中使用。
示例:保存用户设置
struct Settings {
static let usernameKey = "username"
static let notificationsKey = "notificationsEnabled"
}
let defaults = UserDefaults.standard
// 保存设置
defaults.set("Alice", forKey: Settings.usernameKey)
defaults.set(true, forKey: Settings.notificationsKey)
// 读取设置
let username = defaults.string(forKey: Settings.usernameKey) ?? "Guest"
let notificationsEnabled = defaults.bool(forKey: Settings.notificationsKey)
print("\(username) has notifications enabled: \(notificationsEnabled)")
总结
在实际的应用过程中,通过UserDefaults存储数据后,每次重新打开应用时,都需要读取数据,否则UserDefaults的数据不会自动加载出来,除非使用@AppStorage属性包装器,@AppStorage简化了存储和读取过程,有精力可以学习一下@AppStorage属性包装器。
@AppStorage("username") private var username: String = "Guest"
为什么重新打开应用时,需要重新读取数据?
这是因为SwiftUI并不会存储数据,当我们尝试将一个数据保存到UserDefaults时:
UserDefaults.standard.set("John", forKey: "username") // 保存字符串
数据会根据forKey把值存储起来。当我们关闭应用的时候,数据在UserDefaults中存储,而不会依据@State之类的属性包装器存储。
所以,我们需要通过下面的代码读取相关的值。
UserDefaults.standard.string
举一个例子,比如你到酒吧喝酒,就没有喝完,需要存起来(存储操作)。隔了一段时间,重新回到酒吧时,进入包间,发现酒迟迟没有上来。这是因为你没有到前台去领取你的酒(读取操作)。
这也就是为什么重新打开应用时,如果不去读取UserDefaults,数据不会重新展示出来。

相关文章
1、Userdefaults存储Set类型数据:https://fangjunyu.com/2024/12/24/userdefaults%e5%ad%98%e5%82%a8set%e7%b1%bb%e5%9e%8b%e6%95%b0%e6%8d%ae/
2、Swift使用UserDefaults保存数据:https://fangjunyu.com/2024/05/26/swift%e4%bd%bf%e7%94%a8userdefaults%e4%bf%9d%e5%ad%98%e6%95%b0%e6%8d%ae/
扩展知识
1、存储自定义对象
UserDefaults 不直接支持存储自定义对象。可以通过将对象编码为 Data 来实现。
定义一个自定义对象:
struct User: Codable {
let name: String
let age: Int
}
保存自定义对象:
let user = User(name: "Alice", age: 30)
if let encoded = try? JSONEncoder().encode(user) {
defaults.set(encoded, forKey: "currentUser")
}
读取自定义对象:
if let savedData = defaults.data(forKey: "currentUser"),
let decodedUser = try? JSONDecoder().decode(User.self, from: savedData) {
print(decodedUser.name) // 输出 "Alice"
}
自定义对象部分涉及编解码的知识,如果有精力,可以看一下《SwiftUI UserDefaults无法解码问题》。
