JSON和Model最佳轉(zhuǎn)換的iOS框架: MJExtension-Swift


手冊(cè)簡(jiǎn)介

JSON和Model最佳轉(zhuǎn)換的iOS框架: MJExtension-Swift

手冊(cè)說明

1.如何導(dǎo)入框架

直接拖拽Reflect文件夾到您的項(xiàng)目中即可,無任何第三方依賴!

文件夾結(jié)構(gòu)說明:

.Coding 歸檔相關(guān)

.Reflect 反射核心包

.Dict2Model 字典轉(zhuǎn)模型

.Model2Dict 模型轉(zhuǎn)字典

提示

注:框架中已為您準(zhǔn)備了大量懶人式示例,并且簡(jiǎn)單到你直接調(diào)用類方法即可查看效果,

1.Parse-Parse8為字典轉(zhuǎn)模型解析系列。

2.Convert1-Convert4為模型轉(zhuǎn)字典系列。

3.Archiver1-Archiver3為歸檔系列。

使用方法如Studetn1.Parse(),Person1.Convert(),Book1.Action()。

2.關(guān)于MJExtension-Swift

我們可以將其理解成是MJExtension的Swift版本,它可以完成類反射、一鍵字典轉(zhuǎn)模型、一鍵模型轉(zhuǎn)字典、一鍵plist轉(zhuǎn)模型以及一鍵歸檔!

MJExtension(OC): https://github.com/CoderMJLee/MJExtension 

(1)反射

直接調(diào)用對(duì)象的properties即可枚舉反射您的對(duì)象

    p1.properties { (name, type, value) -> Void in        println("\(name),\(type),\(value)")    }

除了使用對(duì)象調(diào)用之外,你還可以不創(chuàng)建對(duì)象,直接類方法調(diào)用,此時(shí)的value無意義:

    Person.properties { (name, type, _) -> Void in        println("\(name),\(type)")    }

其中name是您的模型的屬性名,type是封裝的ReflectType數(shù)據(jù)類型,value是變量的值, 重度使用者請(qǐng)?jiān)敿?xì)參考ReflectType的封裝,您可以詳細(xì)的知道每個(gè)屬性是什么情況,如:

具體的數(shù)據(jù)類型.是否是基本數(shù)據(jù)類型.是否為數(shù)組.是否為Optional.是否為OC過來的對(duì)象.是否為自定義的Class類

var typeName: String!/**  系統(tǒng)解析出的Type  */var typeClass: Any.Type!var disposition: MirrorDisposition!var dispositionDesc: String!/**  是否是可選類型  */var isOptional: Bool = false/**  是否是數(shù)組  */var isArray: Bool = false/**  真實(shí)類型: 可選 + 數(shù)組  */var realType: RealType = .None

,除了上面介紹的功能之外,還加入了仿OC打?。?你可以直接打印您的對(duì)象,比如打印Book1對(duì)象(BOOK1類位于項(xiàng)目中的Archiver1.swift中):

println(book1)

控制臺(tái)會(huì)這樣輸出:

Reflect.Book1 <0x7a09fb10>: {name: tvbprice: 36.6}

附加功能之解析過程的字段映射與字段忽略,子類只需重寫此方法即可:

/**  字段映射  *///使用模型的userModel屬性去解析并接受字典中的user_model鍵值對(duì)func mappingDict() -> [String: String]? {    return ["userModel":"user_model"]}  /**  字段忽略  *///忽略并且不解析模型的info屬性func ignorePropertiesForParse() -> [String]? {    return ["info"]}

您還可以使用以下方法完成字符串向類的轉(zhuǎn)變:

let cls = ClassFromString("Reflect.Person")

不過請(qǐng)注意,這里的字符串是含有命名空間的。

(2)一鍵字典轉(zhuǎn)模型

字典轉(zhuǎn)模型非常簡(jiǎn)單,已做各種級(jí)聯(lián),這里不再贅述細(xì)節(jié)了:

let stu1 = Student1.parse(dict: Student1Dict)let stus = Student7.parses(arr: Student7DictArr)

如果你屬性為Bool,你可能會(huì)遇到UndefinedKey,這是因?yàn)閟wift自身的原因,你只需實(shí)現(xiàn)以下方法手動(dòng)解析:

override func setValue(value: AnyObject?, forUndefinedKey key: String) {    self.isVip = (value as! Int) != 0}

解析Plist文件,請(qǐng)不要帶后綴:

let author = Author.parsePlist("Author")

(3)一鍵模型轉(zhuǎn)字典

模型轉(zhuǎn)字典也非常簡(jiǎn)單,已做各種級(jí)聯(lián),這里不再贅述細(xì)節(jié)了:

let dict = person3.toDict()

(4)一鍵歸檔

歸檔已做了級(jí)聯(lián),使用同樣簡(jiǎn)單,同時(shí)封裝了Caches文件夾的操作,直接保存在Caches文件夾中

歸檔:?jiǎn)蝹€(gè)模型歸檔name可為空,數(shù)組時(shí)name值不可為空,返回歸檔位置

let path1 =  Book2.save(obj: book2, name: nil)let path2 =  Book3.save(obj: bookArr, name: "book3")

讀?。赫?qǐng)使用同樣的key,如保存沒有使用name為nil,讀取同樣使用nil

let arcBook2 = Book2.read(name: nil)let arr = Book3.read(name: "book3")

刪除數(shù)據(jù):

Book1.delete(name: nil)

附加功能:歸檔字段忽略

/**  歸檔字段忽略  *///不歸檔模型中的icon字段func ignoreCodingPropertiesForCoding() -> [String]? {    return ["icon"]}

3.解釋下對(duì)該框架存在的某些疑問。

 (1)這個(gè)框架并不是對(duì)MJExtension的純Swift翻譯

,雖然MJExtension-Swift與MJExtension有著相差無異的功能,但是它們兩個(gè)的底層差別甚多??赡艽蠹矣X得在反射這方面它們體現(xiàn)出的功能效果是一樣的,但其實(shí)它們的基本代碼并無相同之處。不過對(duì)于一鍵互轉(zhuǎn)字典-模型來說,它們都是基于反射功能上實(shí)現(xiàn)的。 

 (2)雖然OC中的Runtime在Swift中經(jīng)測(cè)試發(fā)現(xiàn)可用,但在Swift中更多的是叫Reflect反射,所以Runtime在Swift中并不是很好用。 

 (3)值得注意的是Swift有全名空間,所以是不需要前綴的,但是將框架命名為CFRuntime是因?yàn)闆]有把使用OC的習(xí)慣改正過來,而OC的Runtime特性個(gè)人比較喜歡,就用了Runtime,而非Swift中的Reflect

 (4)它并不支持Swfit中的結(jié)構(gòu)體噢,兩點(diǎn)原因: 結(jié)構(gòu)體主要用于數(shù)據(jù)結(jié)構(gòu),是值類型,大型數(shù)據(jù)使用引用類型的類更好。 從繼承的角度來說,繼承自NSObject,就已經(jīng)說明問題。

4.結(jié)語(yǔ) 

   寫出這套框架是由于個(gè)人對(duì)于MJExtension太過依賴,但是公司的項(xiàng)目已經(jīng)全部Swift化,所以只好抓緊時(shí)間在參考大量資料和綜合了MJExtension理念的情況下寫出來,該框架的API與MJExtension保持高度一致,如果你會(huì)使用MJExtension,那么上手CFRuntime基本沒多大問題。

更新記錄

在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)