最近開始研究一些swift的實用三方庫,發(fā)現(xiàn)ObjectMapper是一個比較好用的json诀蓉、模型相互轉(zhuǎn)換的三方庫幅垮。下面就總結(jié)一下ObjectMapper的一些基本使用
一: 創(chuàng)建Model
ObjectMapper中定義了一個協(xié)議Mappable岭接,需要創(chuàng)建一個遵循協(xié)議的model冕末,并實現(xiàn)協(xié)議中聲明的兩個方法
class testModel: Mappable {
var name: String! = ""
var age: String! = ""
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
name <- map["name"]
age <- map["age"]
}
}
二: 轉(zhuǎn)Model
單條數(shù)據(jù)轉(zhuǎn)換
提供的有map開頭的四種方法可供使用,分別是JSON喇肋、JSONObject坟乾、JSONString、JSONfile苟蹈。和直接用model初始化去轉(zhuǎn)的JSON糊渊、JSONString兩種方法
let dic = ["name" : "zhangsan", "age" : "22"]
// 字典轉(zhuǎn)json字符串
let data : Data! = try? JSONSerialization.data(withJSONObject: dic, options: []) as Data?
let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
// 需要傳[String: Any]格式數(shù)據(jù),也就是字典即可
let model1 = Mapper<TestWSModel>().map(JSON: dic)
// 傳Any也就是任何格式數(shù)據(jù)都可以慧脱,但是我們點進去后可以發(fā)現(xiàn)渺绒,如果不是[String: Any]格式,直接返回nil
let model2 = Mapper<TestWSModel>().map(JSONObject: dic)
let model3 = Mapper<TestWSModel>().map(JSONObject: JSONString! as String)
// 傳string格式數(shù)據(jù)菱鸥,也就是json字符串
let model4 = Mapper<TestWSModel>().map(JSONString: JSONString! as String)
// 傳string格式數(shù)據(jù)宗兼,也就是文件路徑(這里沒測試)
let model5 = Mapper<TestWSModel>().map(JSONfile: JSONString! as String)
// 需要傳[String: Any]格式數(shù)據(jù),也就是字典即可
let model6 = TestWSModel(JSON: dic)
// 傳string格式數(shù)據(jù)氮采,也就是json字符串
let model7 = TestWSModel(JSONString: JSONString! as String)
printLog((model1?.name ?? "") as String)
printLog((model2?.name ?? "") as String)
printLog((model3?.name ?? "") as String)
printLog((model4?.name ?? "") as String)
printLog((model6?.name ?? "") as String)
printLog((model7?.name ?? "") as String)
輸出結(jié)果:
2023-04-24 14:16:31.543: zhangsan
2023-04-24 14:16:31.556: zhangsan
2023-04-24 14:16:31.556:
2023-04-24 14:16:31.556: zhangsan
2023-04-24 14:16:31.556: zhangsan
2023-04-24 14:16:31.556: zhangsan
正常來說單條數(shù)據(jù)轉(zhuǎn)換基本實現(xiàn)字典或者json字符串轉(zhuǎn)model即可殷绍,字典轉(zhuǎn)使用JSON、JSONObject都可以鹊漠,json字符串轉(zhuǎn)使用JSONObject不報錯主到,但是轉(zhuǎn)換結(jié)果為nil茶行,需要使用JSONString去轉(zhuǎn)。
另:這四個轉(zhuǎn)換方法都對應(yīng)有一個加toObject參數(shù)的轉(zhuǎn)換方法
let dic1 = ["userName" : "zhangsan", "age" : "22"]
let dic2 = ["name" : "lisi", "age" : "23"]
let model1 = Mapper<TestWSModel>().map(JSON: dic1, toObject: TestWSModel(JSON: dic2)!)
printLog((model1.name ?? "") as String)
printLog((model1.age ?? "") as String)
輸出結(jié)果:
2023-04-24 14:33:17.414: lisi
2023-04-24 14:33:17.431: 22
可以發(fā)現(xiàn)轉(zhuǎn)換后的model登钥,name取得是dic2的值畔师,age取得是dic1的值,也就是這個轉(zhuǎn)換方法是現(xiàn)在dic1里面取值牧牢,如果沒有對應(yīng)的key則從toObject參數(shù)dic2里面取看锉。
mapDictionary開頭方法使用
let dic = ["name" : "zhangsan", "age" : "22"]
let dic1 = ["person" : dic, "personnn" : dic,]
// 使用方法上和map開頭方法大致相同,只是在要轉(zhuǎn)model的字典外面再加一層塔鳍,相當(dāng)于把要轉(zhuǎn)model的字典當(dāng)value
let model = Mapper<TestWSModel>().mapDictionary(JSON: dic1, toDictionary: ["person" : TestWSModel(JSON: dic)!])
printLog(model["person"]?.name)
多條數(shù)據(jù)轉(zhuǎn)換
提供的有mapArray開頭的四種方法可供使用伯铣,分別是JSONArray、JSONObject轮纫、JSONString腔寡、JSONfile。
let dic = ["name" : "zhangsan", "age" : "22"]
var array: [[String : Any]] = []
for _ in 0 ..< 100 {
array.append(dic)
}
// 數(shù)組轉(zhuǎn)json字符串
let data : Data! = try? JSONSerialization.data(withJSONObject: array, options: []) as Data?
let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
// 需要傳[String: Any]格式的數(shù)組即可
let array1 = Mapper<TestWSModel>().mapArray(JSONArray: array)
// 傳Any也就是任何格式數(shù)據(jù)都可以蜡感,但是我們點進去后可以發(fā)現(xiàn)蹬蚁,如果不是[String: Any]格式的數(shù)組,直接返回nil
let array2 = Mapper<TestWSModel>().mapArray(JSONObject: array)
let array3 = Mapper<TestWSModel>().mapArray(JSONObject: JSONString! as String)
// 傳string格式數(shù)據(jù)郑兴,也就是json字符串
let array4 = Mapper<TestWSModel>().mapArray(JSONString: JSONString! as String)
// 傳string格式數(shù)據(jù),也就是文件路徑(這里沒測試)
let array5 = Mapper<TestWSModel>().mapArray(JSONfile: JSONString! as String)
let model1 = array1[0]
let model2 = array2?[0]
let model3 = array3?[0]
let model4 = array4?[0]
printLog((model1.name ?? "") as String)
printLog((model2?.name ?? "") as String)
printLog((model3?.name ?? "") as String)
printLog((model4?.name ?? "") as String)
輸出結(jié)果:
2023-04-24 15:47:21.870: zhangsan
2023-04-24 15:47:21.872: zhangsan
2023-04-24 15:47:21.872:
2023-04-24 15:47:21.872: zhangsan
正常來說多條數(shù)據(jù)轉(zhuǎn)換基本實現(xiàn)數(shù)組或者json字符串轉(zhuǎn)model即可贝乎,數(shù)組轉(zhuǎn)使用JSONArray情连、JSONObject都可以,json字符串轉(zhuǎn)使用JSONObject不報錯览效,但是轉(zhuǎn)換結(jié)果為nil却舀,需要使用JSONString去轉(zhuǎn)。
三: Model轉(zhuǎn)出
model轉(zhuǎn)字典
let dic1 = model?.toJSON()
let dic2 = Mapper().toJSON(model!)
model轉(zhuǎn)json字符串
let jsonStr1 = model?.toJSONString(prettyPrint: true)
let jsonStr2 = Mapper().toJSONString(model!, prettyPrint: true)
model數(shù)組轉(zhuǎn)字典數(shù)組
let array1 = array.toJSON()
let array2 = Mapper().toJSONArray(array)
四:轉(zhuǎn)Model耗時
let dic = ["name" : "zhangsan", "age" : "22"]
var array: [[String : Any]] = []
for _ in 0 ..< 500000 {
array.append(dic)
}
// 數(shù)組轉(zhuǎn)json字符串
let data : Data! = try? JSONSerialization.data(withJSONObject: array, options: []) as Data?
let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
printLog("JSONArray數(shù)組轉(zhuǎn)model開始")
// 需要傳[String: Any]格式的數(shù)組即可
let array1 = Mapper<TestWSModel>().mapArray(JSONArray: array)
printLog("JSONArray數(shù)組轉(zhuǎn)model結(jié)束")
printLog("JSONObject數(shù)組轉(zhuǎn)model開始")
let array2 = Mapper<TestWSModel>().mapArray(JSONObject: array)
printLog("JSONObject數(shù)組轉(zhuǎn)model結(jié)束")
printLog("json字符串轉(zhuǎn)model開始")
let array3 = Mapper<TestWSModel>().mapArray(JSONString: JSONString! as String)
printLog("json字符串轉(zhuǎn)model結(jié)束")
輸出結(jié)果:
2023-04-24 15:58:13.045: JSONArray數(shù)組轉(zhuǎn)model開始
2023-04-24 15:58:14.999: JSONArray數(shù)組轉(zhuǎn)model結(jié)束
2023-04-24 15:58:14.999: JSONObject數(shù)組轉(zhuǎn)model開始
2023-04-24 15:58:16.961: JSONObject數(shù)組轉(zhuǎn)model結(jié)束
2023-04-24 15:58:16.961: json字符串轉(zhuǎn)model開始
2023-04-24 15:58:20.195: json字符串轉(zhuǎn)model結(jié)束
對50萬條2個字段數(shù)組進行轉(zhuǎn)換锤灿,直接array轉(zhuǎn)model挽拔,用JSONArray和JSONObject方法耗時大概一致,都是2秒左右但校,用json字符串轉(zhuǎn)model則需要3秒多一點螃诅。
同樣50萬條數(shù)據(jù),進行不同處理后状囱,使用JSONArray方法轉(zhuǎn)換結(jié)果對比
區(qū)別 | 時間 |
---|---|
2個字段术裸,且對應(yīng)value簡單 | 2秒左右 |
2個字段,且對應(yīng)value復(fù)雜 | 2.1到2.2秒左右 |
轉(zhuǎn)換的數(shù)組為2個字段亭枷,對應(yīng)模型10個字段 | 接近5秒 |
轉(zhuǎn)換的數(shù)組為10個字段袭艺,對應(yīng)模型2個字段 | 2秒左右 |
轉(zhuǎn)換的數(shù)組為10個字段,對應(yīng)模型10個字段 | 8.5秒左右 |
可以發(fā)現(xiàn)時間跟轉(zhuǎn)換的字段的多少關(guān)系比較大叨粘,字段長度關(guān)系不大
四:初始化一個空model
將NSObject協(xié)議添加到model里面猾编,然后添加一個init方法即可
class TestWSModel: NSObject,Mappable
override init() {
super.init()
}
let model1: TestWSModel? = TestWSModel()
model1?.name = "zhangsan"
五:嵌套對象
嵌套對象為字典瘤睹,兩種處理方法
字典對象直接用當(dāng)前model接收
class TestWSModel: NSObject,Mappable {
var name: String! = ""
var achievement: Dictionary<String, Any>! = [:]
var chinese: String! = ""
var maths: String! = ""
override init() {
super.init()
}
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
name <- map["name"]
achievement <- map["achievement"]
chinese <- map["achievement.chinese"]
maths <- map["achievement.maths"]
}
}
let dic = ["name" : "zhangsan", "age" : "22", "achievement" : ["chinese" : "99", "maths" : "88"]] as [String : Any]
// 需要傳[String: Any]格式數(shù)據(jù),也就是字典即可
let model = Mapper<TestWSModel>().map(JSON: dic)
printLog(model?.name)
printLog(model?.achievement)
printLog(model?.chinese)
printLog(model?.maths)
輸出結(jié)果:
2023-04-25 13:57:28.781: Optional("zhangsan")
2023-04-25 13:57:28.783: Optional(["chinese": "99", "maths": "88"])
2023-04-25 13:57:28.784: Optional("99")
2023-04-25 13:57:28.784: Optional("88")
字典用另外一個model接收
class TestWSModel: NSObject,Mappable {
var name: String! = ""
var achievement: achievementModel! = AchievementModel()
override init() {
super.init()
}
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
name <- map["name"]
achievement <- map["achievement"]
}
}
class AchievementModel: NSObject,Mappable {
var chinese: String! = ""
var maths: String! = ""
override init() {
super.init()
}
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
chinese <- map["chinese"]
maths <- map["maths"]
}
}
let dic = ["name" : "zhangsan", "age" : "22", "achievement" : ["chinese" : "99", "maths" : "88"]] as [String : Any]
// 需要傳[String: Any]格式數(shù)據(jù)答倡,也就是字典即可
let model = Mapper<TestWSModel>().map(JSON: dic)
printLog(model?.name)
printLog(model?.achievement)
printLog(model?.achievement.chinese)
printLog(model?.achievement.maths)
輸出結(jié)果:
2023-04-25 14:01:06.049: Optional("zhangsan")
2023-04-25 14:01:06.051: Optional(<TestSwift.AchievementModel: 0x600001fc8720>)
2023-04-25 14:01:06.051: Optional("99")
2023-04-25 14:01:06.051: Optional("88")
嵌套對象為數(shù)組
class TestWSModel: NSObject,Mappable {
var name: String! = ""
var achievement: Array<AchievementModel>! = []
override init() {
super.init()
}
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
name <- map["name"]
achievement <- map["achievement"]
}
}
class AchievementModel: NSObject,Mappable {
var chinese: String! = ""
var maths: String! = ""
override init() {
super.init()
}
required init?(map: Map) {
}
func mapping(map: ObjectMapper.Map) {
chinese <- map["chinese"]
maths <- map["maths"]
}
}
let dic = ["name" : "zhangsan", "age" : "22", "achievement" : [["chinese" : "99", "maths" : "88"], ["chinese" : "77", "maths" : "66"]]] as [String : Any]
// 需要傳[String: Any]格式數(shù)據(jù)轰传,也就是字典即可
let model = Mapper<TestWSModel>().map(JSON: dic)
printLog(model?.name)
printLog(model?.achievement)
for achModel in model!.achievement {
printLog(achModel.chinese)
printLog(achModel.maths)
}
輸出結(jié)果:
2023-04-25 14:25:08.579: Optional("zhangsan")
2023-04-25 14:25:08.581: Optional([<TestSwift.AchievementModel: 0x6000005d2820>, <TestSwift.AchievementModel: 0x6000005d23d0>])
2023-04-25 14:25:08.582: Optional("99")
2023-04-25 14:25:08.582: Optional("88")
2023-04-25 14:25:08.582: Optional("77")
2023-04-25 14:25:08.582: Optional("66")