MappingAce github地址: https://github.com/IcyButterfly/MappingAce
序幕:開發(fā)者與MappingAce的對(duì)話
-
開發(fā)者: 現(xiàn)在很多開源庫(kù)都是采用的在源代碼里添加屬性與對(duì)應(yīng)key的映射代碼怒见,你也是采用這樣的方式嗎俗慈?
MappingAce: 不是的,基本可以告別這種方式 -
開發(fā)者: 有些JSON解析庫(kù) 雖然也是Swift寫的,但是還是繼承自NSObject來(lái)做的遣耍,你是繼承自NSObject嗎闺阱?
MappingAce: 不是的 -
開發(fā)者: 我需要有些屬性可為nil,另一些屬性非空舵变,你可以給我自動(dòng)處理嗎酣溃?
MappingAce: 嗯 -
開發(fā)者: 那枚舉類型你可以也幫我解析掉嗎?
MappingAce: 嗯 -
開發(fā)者: 聽起來(lái)還可以纪隙,那給我看看吧
MappingAce: 好的赊豌,先給您做個(gè)簡(jiǎn)介,我是一個(gè)Swift JSON解析庫(kù)绵咱,現(xiàn)在支持結(jié)構(gòu)體與類的自動(dòng)解析碘饼,在屬性名字和字典里的key相同的時(shí)候,是不需要寫字典key與屬性的映射代碼的悲伶,接下來(lái)給您演示如何使用
場(chǎng)景1 結(jié)構(gòu)體映射
[開發(fā)者 問(wèn):] 假設(shè)有一個(gè)PhoneNumber結(jié)構(gòu)體艾恼,有如下屬性,該怎么做?
struct PhoneNumber{
var tel: String
var type: String
}
MappingAce: 只需要實(shí)現(xiàn)一下協(xié)議Mapping
像這樣:
struct PhoneNumber: Mapping{
var tel: String
var type: String
}
然后即可使用Mapping里的方法麸锉,解析字典到對(duì)象了
let phoneInfo: [String : Any] = [
"tel": "186xxxxxxxx",
"type": "work"
]
let phone = PhoneNumber(fromDic: phoneInfo)
print(phone.tel) //"186xxxxxxxx"
print(phone.type) //"work"
場(chǎng)景2 結(jié)構(gòu)體嵌套映射
[開發(fā)者 問(wèn):] 那如果是嵌套類型呢钠绍?
MappingAce:
一樣的,嵌套的需要解析的結(jié)構(gòu)體僅需要實(shí)現(xiàn)一下Mapping
協(xié)議即可,假設(shè)上面的PhoneNumber是結(jié)構(gòu)體User的子屬性
struct User{
var age: Int
var name: String
var phone: PhoneNumber
}
使用方法和上面差不多
let dic: [String : Any] = [
"age" : 24,
"name": "Binglin",
"phone": phoneInfo
]
let user = User(fromDic: phoneInfo)
假設(shè)屬性里有數(shù)組淮椰,數(shù)組的Element是需要解析的結(jié)構(gòu)體五慈,也只需要實(shí)現(xiàn)下協(xié)議
Mapping
纳寂,剩下的我都替你做好了
場(chǎng)景3 屬性為Optional
MappingAce: 對(duì)于可空屬性主穗,我也是支持的
struct User: Mapping{
var age: Int?
var name: String?
var phone: PhoneNumber?
}
struct PhoneNumber: Mapping {
var tel: String
var type: String
}
let dic: [String : Any] = [
"name": "Binglin",
]
let user = User(fromDic: dic)
print(user.age)//nil
print(user.name)//Binglin
print(user.phone?.tel)//nil
print(user.phone?.type)//nil
場(chǎng)景4 枚舉
MappingAce:對(duì)于枚舉,目前我們支持Int和String類型
對(duì)于Int 實(shí)現(xiàn)一下EnumInt
協(xié)議
enum Gender: Int, EnumInt{
case male = 1
case female = 2
}
就可以為您自動(dòng)轉(zhuǎn)換了
struct User: Mapping{
var gender: Gender
}
let dicGender: [String : Any] = ["gender": 1]
let userMale = User(fromDic: dicGender)
XCTAssertEqual(userMale.gender, Gender.male)
String類型的話毙芜,也是實(shí)現(xiàn)一下協(xié)議
EnumString
,剩下的就可以交給我了
場(chǎng)景5 有默認(rèn)值的結(jié)構(gòu)體和類
MappingAce: 如果是結(jié)構(gòu)體屬性設(shè)置了默認(rèn)值 或者是類(OC的或者Swift的類)忽媒,是需要實(shí)現(xiàn)InitMapping
而不是實(shí)現(xiàn)上面的Mapping
協(xié)議的
InitMapping
里有一個(gè)方法需要實(shí)現(xiàn)一下
init()
對(duì)于結(jié)構(gòu)體
struct User: InitMapping{
var name: String = "default"
var age: Int?
}
let dic: [String : Any] = ["age": 14]
let user = User(fromDic: dic)
print(user.name) //"default"
print(user.age) //14
對(duì)于類的話 情況會(huì)稍微復(fù)雜一點(diǎn) 會(huì)有一個(gè)required override init() {}
class User: NSObject, InitMapping{
var name: String = "default"
var age: Int?
required override init() {}/*required*/
}
let dic: [String : Any] = ["name" : "IB"]
let user = User(fromDic: dic)
場(chǎng)景5 Model -> JSON
MappingAce:這個(gè)也許是最容易的了,如果你實(shí)現(xiàn)了Mapping
或者InitMapping
的話腋粥,已經(jīng)提供了方法
struct PhoneNumber: Mapping {
var tel: String
var type: String
}
let phone = PhoneNumber(tel: "186xxxxxxxx", type: "work")
let toDic = phone.toDictionary()
print(toDic) // ["type": "work", "tel": "186xxxxxxxx"]
如果你沒(méi)實(shí)現(xiàn)上面兩個(gè)協(xié)議那么你只需要實(shí)現(xiàn)一下協(xié)議Serializable
晦雨,就使用默認(rèn)實(shí)現(xiàn)的方法了
struct `ABC`: `Serializable` {
var tel: String
var type: String
}
let abc = `ABC`(tel: "186xxxxxxxx", type: "work")
let toDic = abc.toDictionary()
print(toDic) // ["type": "work", "tel": "186xxxxxxxx"]
當(dāng)然,如果想要正確獲取嵌套類型的話隘冲,嵌套的類型還是建議實(shí)現(xiàn)一下協(xié)議Mapping
, 不需要實(shí)現(xiàn)協(xié)議里的方法的啦
尾聲
開發(fā)者: 嗯 看起來(lái)用MappingAce的話 開發(fā)上面還是挺有效率的闹瞧,就是不知道性能和ObjectMapper和SwiftyJSON相比怎么樣
MappingAce: 這個(gè)我也有測(cè)試
以下面的結(jié)構(gòu)體循環(huán)解析10000次為例子
struct User{
var name: String
var age: Int
var phoneNumber: PhoneNumber
}
struct PhoneNumber {
var tel: String
var type: String
}
解析耗費(fèi)時(shí)間 [iPhone6 Plus]
有朋友指出最開始結(jié)尾的時(shí)間推翻了整片文章,是因?yàn)槭謱憰r(shí)間少寫了一個(gè)零 導(dǎo)致最終顯示MappingAce解析所耗費(fèi)的時(shí)間最多展辞,故現(xiàn)直接截圖單元測(cè)試的時(shí)間結(jié)果
MappingAce: MappingAce現(xiàn)已上傳到github奥邮, 支持?Carthage& CocoaPods,
https://github.com/IcyButterfly/MappingAce
歡迎拍磚,star