iOS数据持久化Plist使用
iOS 端数据持久化就是把数据保存在本地,常用于基本信息储存,应用配置,应用支持数据源,网络请求缓存等。主要有如下几种方式:方式 | 介绍 | 特点 |
---|---|---|
Plist文件 | 属性列表(Property List),通过xml的方式保存 | 本质为XML格式 |
Preference(NSUserDefaults) | 偏好设置,通过key-value存取,一般用于基本用户信息储存 | 方便存取 |
Keychain | 钥匙串,通过key-value保存在系统keychain中,常用于安全性高的数据存储,比如密码,账号等。 | 安全,不会随应用删除而丢失 |
NSKeyedArchiver | 归档与解档,存储对象需要遵守NSCoding协议 | |
SQLite3 | 小型数据库存储库,一般使用基于它封装的其他开源库 | 数据库储存 |
RMDB | git最受欢迎基于sqlite的iOS开源库 | 数据库储存 |
WCDB | 微信团队基于sqlite实现的ORM特性开源项目 | 数据库储存 |
CoreData | 苹果官方基于sqlite封装的ORM库 | 数据库储存 |
Realm | 一款流行的开源数据库,操作简单 | 跨平台,数据库储存 |
沙盒
iOS系统安全性高的原因之一是,应用都在沙盒之中运行,保证安全性。大部分本地化,可以选择数据存放路径,理解沙盒下目录的特点,能让我们选择最合适的目录。
文件 | 描述 |
---|---|
应用程序包 | 包含应用所有资源和可执行文件 |
Documents | iTunes会同步该目录 |
tmp | iTunes不会同步,保存运行时的临时数据,且会删除 |
Library/Cache | iTunes不会同步,一般存放体积大且不需要备份的不重要数据 |
Library/Preference | iTunes不会同步,保存偏好设置和应用设置 |
获取沙盒根目录:
let homePath = NSHomeDirectory()
Plist文件
Plist文件适合配置项数据,比如应用配置,应用支持数据源(城市数据源)等基本数据类型可以满足的持久化
可视化创建Plist
比如项目中的info.plist文件就是一个可视化的plist,我们可以方便的可视化编辑和浏览。同样的,自己也可以创建。
在Xcode的目录下点击新建,选择iOS下的Resource 选择Property List,如下图:
在Plist文件中写入城市数据后:
读取Plist文件数据,读取路径之后,可以通过字典方式读取出来。
代码读写Plist文件
NSDictionary和NSArray支持直接读写Plist文件,但是使用Swift的标准的Dictionary和Array需要通过PropertyListSerilization做中转。
以下使用两种方式读写plist,基本数据如下:
let dic: [String: Any] = ["name": "张三", "age": 20, "friends":["Tome", "Jack", "Rose"]]
let nsPath = NSHomeDirectory() + "/Documents/nsUserInfo.plist"
let swiftPath = NSHomeDirectory() + "/Documents/swiftUserInfo.plist"
使用NSDictionary/NSArray直接读写
如果在Swift中想直接读写,可以通过NSArray和NSDictionary中转
private func writeToPlistByNSDic(){
let nsDic = NSDictionary(dictionary: dic) // Swift字典转为NS字典
let result = nsDic.write(to: URL(fileURLWithPath: nsPath),atomically: true)
}
private func readPlistByNSDic() {
let nsDic = NSDictionary(contentsOfFile: nsPath) // 通过NS字典读,然后转为Swift字典
print("读取到NSDic:\(nsDic)")
if let temp = nsDic, let swiftDic = temp as? [String: Any] {
print(swiftDic)
}
}
使用Swift原生方式读写Plist
如果使用Swift原生字典,需要通过PropertyListSerialization来序列化之后再读写。
private func writeToPlistBySwiftDic() {
let data = try? PropertyListSerialization.data(fromPropertyList: dic, format: .xml, options: PropertyListSerialization.WriteOptions.max) //先转换为data
do {
try data?.write(to: URL(fileURLWithPath: swiftPath)) // 写入
} catch let error {
print(error)
}
}
private func readPlistBySwiftDic() {
guard let plistData = FileManager.default.contents(atPath: swiftPath) else { //读出data
print("未读取到plist数据")
return
}
let plist = try? PropertyListSerialization.propertyList(from: plistData, options: .mutableContainers, format: nil) //再序列化为字典
guard let plistDic = plist as? [String: Any] else {
return
}
print("读取到SwiftDic:\(plistDic)")
}
运行结果:
读取到NSDic:Optional({
age = 20;
friends = (
Tome,
Jack,
Rose
);
name = "\U5f20\U4e09";
})
["age": 20, "friends": <__NSArrayM 0x600003a47720>(
Tome,
Jack,
Rose
)
, "name": 张三]
读取到SwiftDic:["name": 张三, "friends": <__NSArrayM 0x6000008d4fc0>(
Tome,
Jack,
Rose
)
, "age": 20]
参考
How To Working With Plist In Swift Swift的Codable对象也支持读写到plist中(通过PropertyEncoder和PropertyDecoder)