Swift開源項目ObjectMapper基本使用

最近開始研究一些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")

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市苇羡,隨后出現(xiàn)的幾起案子绸吸,更是在濱河造成了極大的恐慌,老刑警劉巖设江,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锦茁,死亡現(xiàn)場離奇詭異,居然都是意外死亡叉存,警方通過查閱死者的電腦和手機码俩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歼捏,“玉大人稿存,你說我怎么就攤上這事⊥啵” “怎么了瓣履?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長练俐。 經(jīng)常有香客問我袖迎,道長,這世上最難降的妖魔是什么腺晾? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任燕锥,我火速辦了婚禮,結(jié)果婚禮上悯蝉,老公的妹妹穿的比我還像新娘归形。我一直安慰自己,他們只是感情好鼻由,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布暇榴。 她就那樣靜靜地躺著,像睡著了一般嗡靡。 火紅的嫁衣襯著肌膚如雪跺撼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天讨彼,我揣著相機與錄音歉井,去河邊找鬼。 笑死哈误,一個胖子當(dāng)著我的面吹牛哩至,可吹牛的內(nèi)容都是我干的躏嚎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼菩貌,長吁一口氣:“原來是場噩夢啊……” “哼卢佣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起箭阶,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虚茶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后仇参,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘹叫,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年诈乒,在試婚紗的時候發(fā)現(xiàn)自己被綠了罩扇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡怕磨,死狀恐怖喂饥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肠鲫,我是刑警寧澤员帮,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站导饲,受9級特大地震影響集侯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帜消,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浓体。 院中可真熱鬧泡挺,春花似錦、人聲如沸命浴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽生闲。三九已至媳溺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碍讯,已是汗流浹背悬蔽。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捉兴,地道東北人蝎困。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓录语,卻偏偏與公主長得像,于是被迫代替她去往敵國和親禾乘。 傳聞我的和親對象是個殘疾皇子澎埠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容