Swift 数据持久化之——NSKeyedArchiver

5,815 阅读2分钟

数据持久化一直是 iOS 开发中必修之课。比较常见的数据持久化方式有以下5种: 1.plist文件(属性列表) 2.preference(偏好设置) 3.NSKeyedArchiver(归档) 4.SQLite 3 5.CoreData

今天主要研究的是NSKeyedArchiver的使用。

NSKeyedArchiver在iOS中是序列化的一种形式,只要遵循了NSCoding协议的对象都可以通过它实现序列化。值得庆幸的是决大多数支持存储数据的Foundation和Cocoa Touch类都遵循了NSCoding协议,因此,对于大多数类来说,归档相对而言还是比较容易实现的。

接下来的示例存储的都是 Data 类型的数据,Data 是遵循了 NSCoding 协议的。

一、存储路径的设置,路径最好设置为全局变量

var filePath : String {
	let manager = FileManager.default
	let url = manager.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
	return url.appendingPathComponent("objects")!.path
}

二、存储、归档

// 存储到第一步设置的路径之下  value 就是你要存储的数据
NSKeyedArchiver.archiveRootObject(value, toFile: filePath)

三、从路径之下读取

// 读取出来的数据格式就是你当时存储的格式,你存的 Data读取的就是 Data ,你存Model 读取的就是 Model。 注意读取出来的 value 是一个可选值 ,需要做处理之后使用
let  value = NSKeyedUnarchiver.unarchiveObject(withFile: filePath)

四、删除。当我们要销毁这个数据应该怎么做呢

// 删除数据,运用的场景有退出登录等
	let exists = FileManager.default.fileExists(atPath: filePath)
		if exists {
			do {
             // 删除路径下存储的数据,做了错误处理,运用do-catch处理,不太理解do-catch的我的文章中有
				try FileManager.default.removeItem(atPath: filePath)
             // 下边两行代码是界面转换和一些数据的处理  可以根据自己的需求来做
				self.dismiss(animated: true, completion: nil)
				self.delegate?.reloadLastViews()
			}catch let error as NSError {
				
				print("error: \(error.localizedDescription)")
		
			}
		}

但是对于本身不遵循 NSCoding 协议的数据类型,要遵循协议之后才能归档。例如我们的 Model 在 Swift 中实现两个方法:

// 以下两个方法是 NSCoding 协议的两个方法  
	/**
	* NSCoding required initializer.
	* Fills the data from the passed decoder
	*/
// 解档  根据 JSON数据中的字段,分解为我们需要的属性
	@objc required init(coder aDecoder: NSCoder)
	{
		data = aDecoder.decodeObject(forKey: "data") as? CurrentUserData
		isFail = aDecoder.decodeObject(forKey: "isFail") as? Bool
		isOk = aDecoder.decodeObject(forKey: "isOk") as? Bool
		
	}
	
	/**
	* NSCoding required method.
	* Encodes mode properties into the decoder
	*/
// 归档  根据属性和对应的字段进行归档
	func encode(with aCoder: NSCoder)
	{
		if data != nil{
			aCoder.encode(data, forKey: "data")
		}
		if isFail != nil{
			aCoder.encode(isFail, forKey: "isFail")
		}
		if isOk != nil{
			aCoder.encode(isOk, forKey: "isOk")
		}
		
	}

然后再根据上边的四个步骤来做就可以了