##iOS 数据持久化之使用 UserDefaults存储轻量级数据、自定义对象
####看了网上的关于UserDefaults的入门用法的讲解,我是真的头皮发麻。可读性太差了。重点笔记如下:
基本数据类型存储
官方文档里说只支持NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary等 Property List Objects(你应该知道 Foundation框架 NS_类和Swift原生数据类型零开销桥接的,所以 “支持” swift原生数据类型)
//示例代码:
UserDefaults.standard.set("1", forKey: "login")
//如果没接触过 UserDefault,就理解为字典,存的键值对,键是Key,通过UserDefaults.standard 的 set 方法存
//取的时候,就是 object 对应的 key 做参数,就返回了
let login = UserDefaults.standard.object(forKey: "login") as! String
//用途:第一次打开APP的引导界面,简单的数据存储
##自定义对象的存储
//假设有自定义一个对象:
class Person {
var id:Int!
var phone:String!
var nickName:String!
var psd:String!
var email:String?
var gender:String!
}
//想把它存起来,则第一步定义一个静态字符串的结构体或枚举,也可以直接用字符串,没关系,没人阻止 :)
enum Str {
static let idKey = "id"
static let phoneKey = "phone"
static let nickNameKey = "nickName"
static let psdKey = "psd"
static let emailKey = "email"
static let genderKey = "gender"
}
//第二步,修改那个类,实现NSCoding(NSObject可以不实现,问题不大)
//NSCoding接口提供了序列化和反序列化对象的时候的编解码方法。这记着加上就行,先不用理解
class Person: NSObject, NSCoding {
var id:Int!
var phone:String!
var nickName:String!
var psd:String!
var email:String?
var gender:String!
///序列化一个对象的时候使用
func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: Str.idKey)
aCoder.encode(phone, forKey: Str.phoneKey)
aCoder.encode(nickName, forKey: Str.nickNameKey)
aCoder.encode(psd, forKey: Str.psdKey)
aCoder.encode(email, forKey: Str.emailKey)
aCoder.encode(gender, forKey: Str.genderKey)
}
///反序列化的时候用
required init?(coder aDecoder: NSCoder) {
id = aDecoder.decodeObject(forKey: Str.idKey) as? Int
phone = aDecoder.decodeObject(forKey: Str.phoneKey) as? String
nickName = aDecoder.decodeObject(forKey: Str.nickNameKey) as? String
psd = aDecoder.decodeObject(forKey: Str.psdKey) as? String
email = aDecoder.decodeObject(forKey: Str.emailKey) as? String
gender = aDecoder.decodeObject(forKey: Str.genderKey) as? String
}
}
//对象要做的做好了,怎么存呢?
//为了代码美观,我们通常把存取操作封装成几个方法:
extension UserDefaults {
//先介绍下 synchronize() 方法,你代码让存一个字符串,并不是立即写到磁盘,而是每隔一段时间系统才写入,调用这个方法立即写入,防止数据丢失。
///存储 自定义对象:
func saveCustomObj(_ obj: NSCoding, key: String){
let encodedObj = NSKeyedArchiver.archivedData(withRootObject: obj)
set(encodedObj, forKey: key)
synchronize()
}
///获取 自定义对象:
func getCustomObj(for key: String) -> Any? {
guard let decodedObj = object(forKey: key) as? Data else{
return nil
}
return NSKeyedUnarchiver.unarchiveObject(with: decodedObj)
}
///存储基本数据类型
func saveBasic(_ value: Any?, for key: String) {
set(value, forKey: key)
synchronize()
}
//提示,cocoaTouch框架的类基本上都实现了 NSObject和NSCoding,比如图片 UIImage,所以直接就用这两个方法完全OK。
}