初衷
眾所周知鲸湃,在OC時(shí)代浓镜,MJ大神使用一句宏定義MJCodingImplementation就搞定了歸解檔中繁瑣的編碼與解碼工作锭魔。而在Swift中,沒有Runtime大法咬荷,在日常編碼過程中遇到需要?dú)w檔的模型冠句,只要寫編碼和解碼方法,就會(huì)寫到吐血幸乒。于是我找到了Swift中的Reflect特性來幫助我們簡化這部分的工作懦底。
效果
在使用JXAutoEncoder這個(gè)工具類之前,要完成一個(gè)類的歸檔工作需要編寫類似以下的代碼
class ArchiverModel: NSObject, NSCoding {
var bool = true
var int = 1
var double = M_PI
var string = ""
var array = ["123", "456"]
var dictionary = ["abc": "cba"]
var data = "hello world".data(using: String.Encoding.utf8)
var date = Date()
/// 歸檔到文件
func archiveToFile() {
var modelFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,
FileManager.SearchPathDomainMask.userDomainMask,
true)[0]
modelFile += "/model.data"
NSKeyedArchiver.archiveRootObject(self, toFile: modelFile)
}
/// 從文件中解檔
///
/// - Returns: 解檔后的Model
class func decodedFromFile() throws -> ArchiverModel {
var modelFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,
FileManager.SearchPathDomainMask.userDomainMask,
true)[0]
modelFile += "/model.data"
if FileManager.default.fileExists(atPath: modelFile) {
if let model = NSKeyedUnarchiver.unarchiveObject(withFile: modelFile) as? ArchiverModel {
return model
}else{
throw NSError(domain: "Unarchive fail", code: 100, userInfo: nil)
}
}else{
throw NSError(domain: "File doesn't exists", code: 101, userInfo: nil)
}
}
required init?(coder aDecoder: NSCoder) {
super.init()
if let boolValue = aDecoder.decodeObject(forKey: "bool") as? Bool {
bool = boolValue
}
if let intValue = aDecoder.decodeObject(forKey: "int") as? Int {
int = intValue
}
if let doubleValue = aDecoder.decodeObject(forKey: "double") as? Double {
double = doubleValue
}
if let stringValue = aDecoder.decodeObject(forKey: "string") as? String {
string = stringValue
}
if let arrayValue = aDecoder.decodeObject(forKey: "array") as? [String] {
array = arrayValue
}
if let dictionaryValue = aDecoder.decodeObject(forKey: "dictionary") as? [String: String] {
dictionary = dictionaryValue
}
if let dataValue = aDecoder.decodeObject(forKey: "data") as? Data {
data = dataValue
}
if let dateValue = aDecoder.decodeObject(forKey: "date") as? Date {
date = dateValue
}
}
func encode(with aCoder: NSCoder) {
aCoder.encode(bool, forKey: "bool")
aCoder.encode(int, forKey: "int")
aCoder.encode(double, forKey: "double")
aCoder.encode(string, forKey: "string")
aCoder.encode(array, forKey: "array")
aCoder.encode(dictionary, forKey: "dictionary")
aCoder.encode(data, forKey: "data")
aCoder.encode(date, forKey: "date")
}
}
密密麻麻的aCoder.encode
看得我密集恐懼癥都犯了逝变,更別說這個(gè)類如果要添加新的屬性會(huì)怎樣了,并且當(dāng)屬性變多奋构,encode和decode就很容易漏寫壳影,造成應(yīng)用崩潰。使用工具類之后弥臼,這種情況就可以完全避免了宴咧,如下所示:
import JXAutoEncoder
class ArchiverModel: JXAutoEncoder {
var bool = true
var int = 1
var double = M_PI
var string = ""
var array = ["123", "456"]
var dictionary = ["abc": "cba"]
var data = "hello world".data(using: String.Encoding.utf8)
var date = Date()
/// 歸檔到文件
func archiveToFile() {
var modelFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,
FileManager.SearchPathDomainMask.userDomainMask,
true)[0]
modelFile += "/model.data"
NSKeyedArchiver.archiveRootObject(self, toFile: modelFile)
}
/// 從文件中解檔
///
/// - Returns: 解檔后的Model
class func decodedFromFile() throws -> ArchiverModel {
var modelFile = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,
FileManager.SearchPathDomainMask.userDomainMask,
true)[0]
modelFile += "/model.data"
if FileManager.default.fileExists(atPath: modelFile) {
if let model = NSKeyedUnarchiver.unarchiveObject(withFile: modelFile) as? ArchiverModel {
return model
}else{
throw NSError(domain: "Unarchive fail", code: 100, userInfo: nil)
}
}else{
throw NSError(domain: "File doesn't exists", code: 101, userInfo: nil)
}
}
}
簡潔明了,干凈透徹径缅,若要增加屬性掺栅,則直接var...就好了,是不是方便了許多纳猪。
部署
JXAutoEncoder這個(gè)工具類支持pod導(dǎo)入氧卧,導(dǎo)入方式pod 'JXAutoEncoder'
,具體可查閱項(xiàng)目主頁。使用中若發(fā)現(xiàn)Bug氏堤,請(qǐng)?zhí)醝ssue沙绝,使用順手請(qǐng)star,謝謝??鼠锈!