开发过程中,我通常会有一些简单的数据存储,如果用数据库,又太重了,所以官方就有提供一些好用的API,方便我们使用。
NSUserDefaults(属性列表)
var userDefault = UserDefaults.standard
userDefault.set(URL(string: "http://github.com"), forKey: "domain")
var domain = userDefault.url(forKey: "domain")
userDefault.set("18", forKey: "age")
var age = userDefault.integer(forKey: "age")
userDefault.set(3.1415926535, forKey: "pi")
// 3.1415926535
var piDouble = userDefault.double(forKey: "pi")
// 3.141592
var piFloat = userDefault.float(forKey: "pi")
userDefault.set(true, forKey: "isLogin")
var isLogin = userDefault.bool(forKey: "isLogin")
userDefault.set(175.5, forKey: "height")
var height = userDefault.float(forKey: "height")
// 写入数据后,数据是先保存在内存中,然后再存储到硬盘上,所以如果遇到断电等行为,需要手动调用synchronize()
userDefault.synchronize()
NSUserDefaults 和 NSKeyedArchiver 实现存储对象
class People:NSObject,NSCoding,NSSecureCoding{
static var supportsSecureCoding: Bool{
return true
}
var name = ""
var age = 0
func encode(with aCoder: NSCoder) {
aCoder.encode(self.name, forKey: "name")
aCoder.encode(self.age, forKey: "age")
}
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
self.age = aDecoder.decodeInteger(forKey: "age")
}
init(name:String,age:Int) {
self.name = name
self.age = age
}
override var description: String{
return "name:\(name),age:\(age)"
}
}
使用
do{
let people = People(name: "Wiki",age: 18)
let data = try NSKeyedArchiver.archivedData(withRootObject: people, requiringSecureCoding: false)
userDefault.set(data, forKey: "people")
}catch{
print(error)
}
do{
let data = userDefault.object(forKey: "people") as! Data
let people = try NSKeyedUnarchiver.unarchivedObject(ofClass: People.self, from: data)
print(people!.description)
}catch{
print(error)
}
NSUserDefaults 和 ObjectMapper 解决方案
NSKeyedArchiver 的使用相对来说比价复杂,我建议是引入一个第三方的库 ObjectMapper
,通过序列化为String,再从String 反序列化到 Object 简化对象的存储。
// User.swift
import ObjectMapper
class User: Mappable {
required init?(map: Map) {}
func mapping(map: Map) {
name <- map["name"]
uid <- map["uid"]
}
var name:String = ""
var uid:Int = 0
}
定义一个管理类,方便我们集中管理
// MyUserDefaults.swift
import ObjectMapper
class MyUserDefaults{
static let instance = MyUserDefaults()
var loginUser:User?{
set{setObject(newValue, forKey: "loginUser")}
get{return getObject(User.self, forKey: "loginUser")}
}
var lastLoginType: Int{
set{userDefault.set(newValue, forKey: "lastLoginType")}
get{return userDefault.integer(forKey: "lastLoginType")}
}
private var userDefault = UserDefaults.standard
private func setObject<T:Mappable>(_ newValue:T?,forKey:String){
if(newValue == nil){
userDefault.set("", forKey: forKey)
}else{
userDefault.set(newValue?.toJSONString(), forKey: forKey)
}
}
private func getObject<T:Mappable>(_ type: T.Type,forKey:String) -> T?{
let text = userDefault.string(forKey: forKey)
if(text == nil || text?.count == 0){
return nil
}else{
return Mapper<T>().map(JSONString: text!)
}
}
}
使用方式
let user = MyUserDefaults.instance.loginUser
MyUserDefaults.instance.loginUser = User()
网友评论