Swift - 本地数据的保存与加载(使用NSCoder将对象保存到.plist文件)
作者:hangge | 2015-05-07 14:20
(本文代码已升级至Swift3)
下面通过一个例子将联系人数据保存到沙盒的“documents”目录中。(联系人是一个数组集合,内部为自定义对象)。
--- DataModel.swift ---
--- UserInfo.swift ---
1,样例功能
(1)点击“保存”将联系人存入 userList.plist 文件中
(2)点击“读取”从数据文件中加载解析出联系人
2,注意事项
(1)本例使用了 NSCoder,这个封装了许多技术细节,使用它我们可以很轻易的将对象写到文件中,也可以用它将文件中的对象转换回来。
(2)自定义对象必须添加如下两个方法,这个才能顺利的被序列化编码存储和读取。
//从object解析回来 required init(coder decoder: NSCoder) { self.name = decoder.decodeObject(forKey: "Name") as? String ?? "" self.phone = decoder.decodeObject(forKey: "Phone") as? String ?? "" } //编码成object func encode(with coder: NSCoder) { coder.encode(name, forKey:"Name") coder.encode(phone, forKey:"Phone") }
3,样例代码
--- ViewController.swift ---import UIKit class ViewController: UIViewController { var dataModel = DataModel() override func viewDidLoad() { super.viewDidLoad() //初始化模拟数据 onCreateData() } //创建模拟数据 func onCreateData(){ dataModel.userList.append(UserInfo(name: "张三", phone: "1234")) dataModel.userList.append(UserInfo(name: "李四", phone: "1212")) dataModel.userList.append(UserInfo(name: "航歌", phone: "3525")) } //保存数据 @IBAction func saveData(_ sender:AnyObject) { dataModel.saveData() print("保存成功!") } //读取数据 @IBAction func loadData(_ sender:AnyObject) { dataModel.loadData() print("读取成功!", dataModel.userList) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
--- DataModel.swift ---
import UIKit class DataModel: NSObject { var userList = [UserInfo]() override init(){ super.init() print("沙盒文件夹路径:\(documentsDirectory())") print("数据文件路径:\(dataFilePath())") } //保存数据 func saveData() { let data = NSMutableData() //申明一个归档处理对象 let archiver = NSKeyedArchiver(forWritingWith: data) //将lists以对应Checklist关键字进行编码 archiver.encode(userList, forKey: "userList") //编码结束 archiver.finishEncoding() //数据写入 data.write(toFile: dataFilePath(), atomically: true) } //读取数据 func loadData() { //获取本地数据文件地址 let path = self.dataFilePath() //声明文件管理器 let defaultManager = FileManager() //通过文件地址判断数据文件是否存在 if defaultManager.fileExists(atPath: path) { //读取文件数据 let url = URL(fileURLWithPath: path) let data = try! Data(contentsOf: url) //解码器 let unarchiver = NSKeyedUnarchiver(forReadingWith: data) //通过归档时设置的关键字Checklist还原lists userList = unarchiver.decodeObject(forKey: "userList") as! Array //结束解码 unarchiver.finishDecoding() } } //获取沙盒文件夹路径 func documentsDirectory()->String { let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let documentsDirectory = paths.first! return documentsDirectory } //获取数据文件地址 func dataFilePath ()->String{ return self.documentsDirectory().appendingFormat("/userList.plist") } }
--- UserInfo.swift ---
import UIKit class UserInfo: NSObject, NSCoding { var name:String var phone:String //构造方法 required init(name:String="", phone:String="") { self.name = name self.phone = phone } //从object解析回来 required init(coder decoder: NSCoder) { self.name = decoder.decodeObject(forKey: "Name") as? String ?? "" self.phone = decoder.decodeObject(forKey: "Phone") as? String ?? "" } //编码成object func encode(with coder: NSCoder) { coder.encode(name, forKey:"Name") coder.encode(phone, forKey:"Phone") } }
4,运行效果
(1)点击“保存”按后,可以看到应用的 documents 目录下便新建了个 userList.plist 文件。(2)打开 userList.plist 文件,可以看到联系人数据已经成功保存到里面了。
全部评论(3)
站长你好,请问一下,当清除数据的时候怎么搞啊
站长回复:那就先把数据清除然后再保存。以本文样例说明,如果要把所有联系人清除,可以执行下面代码:
dataModel.userList = []
dataModel.saveData()
站长你好!在这里受益颇多。有个问题想请教。
文件已经下载到/Documents当中。请问如何通过代码删除。谢谢!
站长回复:可以我原来写的这篇文章:Swift - 文件,文件夹操作大全(http://www.hangge.com/blog/cache/detail_527.html)
loadData()以后,怎么获得里边的具体内容啊??
站长回复:NSCoder功能是把对象存储到plist文件中,下次再从这个文件里把这些对象还原出来。
你看loadData()里,就有把数据读取,解析成userList这个数组集合(代码39行)