在介紹存儲方案之前有必要說下沙盒機(jī)制徐块,詳見:iOS中的沙盒目錄
數(shù)據(jù)持久化,其實(shí)就是將數(shù)據(jù)寫入到硬盤的方式毛秘,使得APP重啟之后可以繼續(xù)使用之前保存的數(shù)據(jù)饭寺。在iOS開發(fā)中,提供了5種數(shù)據(jù)持久化方案:
- plist
- Preference
- NSKeyedArchiver
- SQLite 3
- CoreData
plist
plist是將一些特定的類通過xml文件轉(zhuǎn)化的方式將數(shù)據(jù)存儲到目錄中叫挟,可以被序列化的類只有:
NSArray
NSDictionary
NSString
NSNumber
NSData
NSDate
1. 獲取文件路徑
let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let plistName = "/user.plist"
2. 讀取
func readPlist() -> AnyObject? {
return NSArray(contentsOfFile: documentsDir + plistName)
}
3.寫入(存儲)
// 存儲時使用writeToFile: atomically:方法艰匙。 其中atomically表示是否需要先寫入一個輔助文件,再把輔助文件拷貝到目標(biāo)文件地址抹恳。這是更安全的寫入文件方法员凝,一般都寫true。
func savePlist() {
let plist = NSArray(array: ["ABC", "EFG", "SSK"])
plist.write(toFile: documentsDir + plistName, atomically: true)
}
Preference
一般是用于存儲用戶的一些偏好設(shè)置和基本用戶信息奋献。比如用戶的id健霹,姓名,APP的字體大小等信息瓶蚂。偏好設(shè)置會將所有數(shù)據(jù)保存到同一個文件中糖埋。即preference目錄下的一個以此應(yīng)用包名來命名的plist文件。
1. 存儲
UserDefaults.standard.set("19658325", forKey: "uid")
UserDefaults.standard.synchronize()
2. 讀取
let uid = UserDefaults.standard.string(forKey: "uid")
NSKeyedArchiver
歸檔在iOS中是另一種形式的序列化窃这,只要遵循了NSCoding協(xié)議的對象都可以通過它實(shí)現(xiàn)序列化存儲阶捆。歸檔這種存儲方式的缺點(diǎn)是沒有preference速度快,優(yōu)點(diǎn)是可以自定義數(shù)據(jù)模型。
1. 定義數(shù)據(jù)模型
class PersonModel: NSObject, NSCoding {
var avatar: UIImage?
var name: String?
// NSCoding協(xié)議聲明了兩個必須實(shí)現(xiàn)的方法洒试,一個用于將對象編碼到歸檔中另一個用于說明如何解檔來獲取新的對象倍奢。
required init(coder aDecoder: NSCoder) {
super.init()
avatar = aDecoder.decodeObject(forKey: "avatar") as? UIImage
name = aDecoder.decodeObject(forKey: "name") as? String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(self.avatar, forKey: "avatar")
aCoder.encode(self.name, forKey: "name")
}
override init() {
}
}
2. 指定路徑
// 文件擴(kuò)展名可以任意指定
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/person.file"
3. 歸檔
func archive() {
let p = PersonModel()
p.name = "大米卡卡"
p.avatar = UIImage(named: "avatar")
NSKeyedArchiver.archiveRootObject(p, toFile: path)
}
4. 解檔
func unarchive() {
if let p = NSKeyedUnarchiver.unarchiveObject(withFile: path) as? PersonModel {
avatarView.image = p.avatar
nameLabel.text = p.name
}
}
SQLite3
CoreData
CoreData本質(zhì)上依然是使用SQLite存儲機(jī)制,只是它不需要編寫一行SQL代碼垒棋。