Swift HandyJSON簡(jiǎn)介和使用

  • 一 簡(jiǎn)介

  • 二 特性

  • 三 安裝使用以及封裝

  • 四 使用示例

一 簡(jiǎn)介

HandyJSON是一個(gè)用于Swift語言中的JSON序列化/反序列化庫制肮。

與其他流行的Swift JSON庫相比,HandyJSON的特點(diǎn)是,它支持純swift類,使用也簡(jiǎn)單惰赋。它反序列化時(shí)(把JSON轉(zhuǎn)換為Model)不要求ModelNSObject繼承(因?yàn)樗皇腔?code>KVC機(jī)制)宠哄,也不要求你為Model定義一個(gè)Mapping函數(shù)。只要你定義好Model類府蛇,聲明它服從HandyJSON協(xié)議,HandyJSON就能自行以各個(gè)屬性的屬性名為Key,從JSON串中解析值敲才。

HandyJSON目前依賴于從Swift Runtime源碼中推斷的內(nèi)存規(guī)則,任何變動(dòng)我們將隨時(shí)跟進(jìn)校坑。

二 特性

  • 序列化ModelJSON穷遂、從JSON反序列化Model
  • 自然地以Model的屬性名稱作為解析JSONKey函匕,不需要額外指定
  • 支持Swift中大部分類型
  • 支持classstruct定義的Model
  • 支持自定義解析規(guī)則
  • 類型自適應(yīng)蚪黑,如JSON中是一個(gè)Int盅惜,但對(duì)應(yīng)ModelString字段,會(huì)自動(dòng)完成轉(zhuǎn)化

三 安裝使用以及封裝

3.1 安裝
我使用的是cocopod進(jìn)行包引入管理忌穿,修改Prodfie文件抒寂,添加如下代碼:

pod 'HandyJSON'

3.2 封裝
為了方便我們項(xiàng)目中的使用,我們一般都會(huì)在做一層封裝掠剑,方便庫的以后升級(jí)替換屈芜,以及方便日常業(yè)務(wù)邏輯的處理

JsonUtil.swift

import UIKit
import HandyJSON
class JsonUtil: NSObject {
    /**
     *  Json轉(zhuǎn)對(duì)象
     */
    static func jsonToModel(_ jsonStr:String,_ modelType:HandyJSON.Type) ->BaseModel {
        if jsonStr == "" || jsonStr.count == 0 {
            #if DEBUG
                print("jsonoModel:字符串為空")
            #endif
            return BaseModel()
        }
        return modelType.deserialize(from: jsonStr)  as! BaseModel

    }

    /**
     *  Json轉(zhuǎn)數(shù)組對(duì)象
     */
    static func jsonArrayToModel(_ jsonArrayStr:String, _ modelType:HandyJSON.Type) ->[BaseModel] {
        if jsonArrayStr == "" || jsonArrayStr.count == 0 {
            #if DEBUG
                print("jsonToModelArray:字符串為空")
            #endif
            return []
        }
        var modelArray:[BaseModel] = []
        let data = jsonArrayStr.data(using: String.Encoding.utf8)
        let peoplesArray = try! JSONSerialization.jsonObject(with:data!, options: JSONSerialization.ReadingOptions()) as? [AnyObject]
        for people in peoplesArray! {
            modelArray.append(dictionaryToModel(people as! [String : Any], modelType))
        }
        return modelArray

    }

    /**
     *  字典轉(zhuǎn)對(duì)象
     */
    static func dictionaryToModel(_ dictionStr:[String:Any],_ modelType:HandyJSON.Type) -> BaseModel {
        if dictionStr.count == 0 {
            #if DEBUG
                print("dictionaryToModel:字符串為空")
            #endif
            return BaseModel()
        }
        return modelType.deserialize(from: dictionStr) as! BaseModel
    }

    /**
     *  對(duì)象轉(zhuǎn)JSON
     */
    static func modelToJson(_ model:BaseModel?) -> String {
        if model == nil {
            #if DEBUG
                print("modelToJson:model為空")
            #endif
             return ""
        }
        return (model?.toJSONString())!
    }

    /**
     *  對(duì)象轉(zhuǎn)字典
     */
    static func modelToDictionary(_ model:BaseModel?) -> [String:Any] {
        if model == nil {
            #if DEBUG
                print("modelToJson:model為空")
            #endif
            return [:]
        }
        return (model?.toJSON())!
    }

}

說明:這里我封裝了5個(gè)方法,Json轉(zhuǎn)對(duì)象朴译,Json轉(zhuǎn)數(shù)組對(duì)象井佑,字典轉(zhuǎn)對(duì)象對(duì)象轉(zhuǎn)JSON动分,對(duì)象轉(zhuǎn)字典,基本覆蓋了我們?nèi)粘i_發(fā)的常用操作毅糟,與這個(gè)工具類相對(duì)應(yīng)的,還有一個(gè)公共的基礎(chǔ)module

BaseModel.swift

import UIKit
import HandyJSON
class BaseModel: HandyJSON {
//    var date: Date?
//    var decimal: NSDecimalNumber?
//    var url: URL?
//    var data: Data?
//    var color: UIColor?

    required init() {}

    func mapping(mapper: HelpingMapper) {   //自定義解析規(guī)則澜公,日期數(shù)字顏色姆另,如果要指定解析格式,子類實(shí)現(xiàn)重寫此方法即可
//        mapper <<<
//            date <-- CustomDateFormatTransform(formatString: "yyyy-MM-dd")
//
//        mapper <<<
//            decimal <-- NSDecimalNumberTransform()
//
//        mapper <<<
//            url <-- URLTransform(shouldEncodeURLString: false)
//
//        mapper <<<
//            data <-- DataTransform()
//
//        mapper <<<
//            color <-- HexColorTransform()
      }
}

說明:封裝的基礎(chǔ)model類坟乾。開發(fā)中迹辐,我們自定義的model繼承此model即可省去了每次都要引入 “import HandyJSON”,以及每次都要實(shí)現(xiàn)“required init() {}”方法甚侣,子類如果要自定義解析規(guī)則明吩,重寫mapping方法即可

四 使用示例

基于以上封裝的類我們實(shí)現(xiàn)幾個(gè)示例做具體說明,主要有以下幾個(gè)示例:

  • Json轉(zhuǎn)模型 (常用)
  • Json數(shù)組轉(zhuǎn)模型 (常用)
  • 字典轉(zhuǎn)模型
  • 模型轉(zhuǎn)Json
  • 模型轉(zhuǎn)字典
  • json與嵌套的模型相互轉(zhuǎn)換特殊類型字段轉(zhuǎn)換殷费,日期類型印荔,數(shù)字類型,顏色
1. Json轉(zhuǎn)模型 (常用)
JsonToModel.swift

import UIKit
class JsonToModel: BaseModel {
    var id :Int?
    var color:String?
    var name:String?
}
 fileprivate func jsonTomodel(){
        let jsonString = "{\"id\":12345,\"color\":\"black\",\"name\":\"cat\"}"
        let model:JsonToModel = JsonUtil.jsonToModel(jsonString,JsonToModel.self) as! JsonToModel
        print(model.name as Any)
        print(model.color as Any)
        print(model.id as Any)
    }

說明:調(diào)用jsonToModel(_ jsonStr:String,_ modelType:HandyJSON.Type),傳入兩個(gè)參數(shù)详羡,第一個(gè)參數(shù)是要轉(zhuǎn)換的Json字符串仍律,第二個(gè)參數(shù)是要轉(zhuǎn)換的model類的class,因?yàn)楣差愔薪y(tǒng)一返回的都是BaseModel類型实柠,所以這里要調(diào)用 as!轉(zhuǎn)換成具體的子類類型水泉。

2. Json數(shù)組轉(zhuǎn)模型 (常用)
JsonArrayToModel.swift

import UIKit
class JsonArrayToModel: BaseModel {
    var name:String?
    var id :String?
}
//json數(shù)組轉(zhuǎn)模型
    fileprivate func jsonArrayTomodel() {
        let jsonArrayString: String = "[{\"name\":\"Bob\",\"id\":\"1\"}, {\"name\":\"Lily\",\"id\":\"2\"}, {\"name\":\"Lucy\",\"id\":\"3\"}]"
        let cats = JsonUtil.jsonArrayToModel(jsonArrayString, JsonArrayToModel.self) as! [JsonArrayToModel]
        for model:JsonArrayToModel  in cats {
            print(model.name as Any)
        }
    }

說明:調(diào)用jsonArrayToModel(_ jsonArrayStr:String, _ modelType:HandyJSON.Type)傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是要轉(zhuǎn)換的數(shù)組型Json字符串,第二個(gè)參數(shù)是要轉(zhuǎn)換的model類的class草则,返回值是一個(gè)數(shù)組钢拧,因?yàn)楣差愔薪y(tǒng)一返回的都是BaseModel類型,所以這里要調(diào)用as!轉(zhuǎn)換成具體的子類類型數(shù)組炕横。

3 字典轉(zhuǎn)模型
import UIKit
class JsonToModel: BaseModel {
    var id :Int!
    var color:String?
    var name:String?
}
//字典轉(zhuǎn)模型
    fileprivate func dicToModel() {
        var dict = [String: Any]()
        dict["id"] = 1.1
        dict["color"] = "hello"
        dict["name"] = "李四"
        let model:JsonToModel = JsonUtil.dictionaryToModel(dict,JsonToModel.self) as! JsonToModel
        print(model.name as Any)
        print(model.color as Any)
        print(model.id as Any)
    }

說明:調(diào)用dictionaryToModel(_ dictionStr:[String:Any],_ modelType:HandyJSON.Type)源内,傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是要轉(zhuǎn)換的字典對(duì)象份殿,第二個(gè)參數(shù)是要轉(zhuǎn)換的model類的class姿锭,因?yàn)楣差愔薪y(tǒng)一返回的都是BaseModel類型,所以這里要調(diào)用as!轉(zhuǎn)換成具體的子類類型伯铣。

4. 模型轉(zhuǎn)Json
JsonToModel.swift

import UIKit
class JsonToModel: BaseModel {
    var id :Int!
    var color:String?
    var name:String?
}
//模型轉(zhuǎn)json
    fileprivate func modelToJson() {
        let model:JsonToModel = JsonToModel()
        model.color = "red"
        model.id    = 100
        model.name  = "李四真"
        let modelTostring = JsonUtil.modelToJson(model)
        print(modelTostring)
    }

說明:調(diào)用modelToJson(_ model:BaseModel?),傳入一個(gè)參數(shù)轮纫,傳入一個(gè)module對(duì)象腔寡,返回值是一個(gè)JSON字符串

5. 模型轉(zhuǎn)字典
JsonToModel.swift

import UIKit
class JsonToModel: BaseModel {
    var id :Int!
    var color:String?
    var name:String?
}
 //模型轉(zhuǎn)字典
    fileprivate func modelTodiction() {
        let model:JsonToModel = JsonToModel()
        model.color = "red"
        model.id    = 100
        model.name  = "李四"
        let modelTostring = JsonUtil.modelToDictionary(model)
        print(modelTostring["name"] as Any)

    }

說明:調(diào)用modelToDictionary(_ model:BaseModel?)傳入一個(gè)參數(shù),傳入一個(gè)module對(duì)象掌唾,返回值是一個(gè)字典對(duì)象放前,對(duì)于日常開發(fā)中,有時(shí)候后臺(tái)只返回一個(gè)字段糯彬,比如返回一個(gè)成功信息字段凭语,直接把返回的json串轉(zhuǎn)換成一個(gè)字典即可,沒必要再構(gòu)建一個(gè)model去轉(zhuǎn)換撩扒。

6. json與嵌套的模型相互轉(zhuǎn)換
CombineModel.swift

import UIKit
class Composition:  BaseModel {
    var aInt:Int?
    var aString:String?
}

class CombineModel: BaseModel {
    var aInt:Int?
    var comp1:Composition?
    var comp2:[Composition] = []

}
//json與嵌套的模型相互轉(zhuǎn)換
    fileprivate func jsonTocombilModel() {
        let model:CombineModel = CombineModel()
        model.aInt = 1001
        let posModel1 = Composition()
        posModel1.aInt = 1
        posModel1.aString = "趙六1"

        let posModel2 = Composition()
        posModel2.aInt = 2
        posModel2.aString = "趙六2"

        let posModel3 = Composition()
        posModel3.aInt = 3
        posModel3.aString = "趙六3"

        model.comp1 = posModel1
        model.comp2.append(posModel2)
        model.comp2.append(posModel3)

        let modeString = JsonUtil.modelToJson(model)
        print(modeString)

        let model2 = JsonUtil.jsonToModel(modeString, CombineModel.self)
        print(model2)
    }

說明:還是調(diào)用Json轉(zhuǎn)模型似扔,模型轉(zhuǎn)Json的方法,本例子演示的是對(duì)象嵌套搓谆,對(duì)象里面可以嵌套對(duì)象炒辉,可以嵌套對(duì)象數(shù)組,平時(shí)我們開發(fā)經(jīng)常遇到這種結(jié)構(gòu)的Json串泉手。

7. 特殊類型字段轉(zhuǎn)換黔寇,日期類型,數(shù)字類型斩萌,顏色
SpacialTypeModel.swift

import UIKit
import HandyJSON
class SpacialTypeModel: BaseModel {
    var date: Date?
    var decimal: NSDecimalNumber?
    var url: URL?
    var data: Data?
    var color: UIColor?

    override func mapping(mapper: HelpingMapper) {
        mapper <<< 
            date <-- CustomDateFormatTransform(formatString: "yyyy-MM-dd")

        mapper <<<
            decimal <-- NSDecimalNumberTransform()

        mapper <<<
            url <-- URLTransform(shouldEncodeURLString: false)

        mapper <<<
            data <-- DataTransform()

        mapper <<<
            color <-- HexColorTransform()
    }

}
// 特殊類型字段轉(zhuǎn)換缝裤,日期類型,數(shù)字類型颊郎,顏色
    fileprivate func jsonToSpecialModel () {

        let object = SpacialTypeModel()
        object.date = Date()
        object.decimal = NSDecimalNumber(string: "1.23423414371298437124391243")
        object.url = URL(string: "https://www.aliyun.com")
        object.data = Data(base64Encoded: "aGVsbG8sIHdvcmxkIQ==")
        object.color = UIColor.blue

        let specailModelString = JsonUtil.modelToJson(object)
        print(object.toJSONString()!)
        // it prints:
        // {"date":"2017-09-11","decimal":"1.23423414371298437124391243","url":"https:\/\/www.aliyun.com","data":"aGVsbG8sIHdvcmxkIQ==","color":"0000FF"}

        let mappedObject:SpacialTypeModel = JsonUtil.jsonToModel(specailModelString, SpacialTypeModel.self) as! SpacialTypeModel
        print(mappedObject.date as Any)
    }

說明:本例演示的是對(duì)于對(duì)象里含有特殊類型字段的轉(zhuǎn)換方法憋飞,主要注意點(diǎn)在構(gòu)建model類里,我們要重寫父類mapping方法還要引入HandyJSON頭文件

swift基礎(chǔ)學(xué)習(xí)

作者鏈接:http://www.reibang.com/p/f2885eed567c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末袭艺,一起剝皮案震驚了整個(gè)濱河市搀崭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖瘤睹,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件升敲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡轰传,警方通過查閱死者的電腦和手機(jī)驴党,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來获茬,“玉大人港庄,你說我怎么就攤上這事∷∏” “怎么了鹏氧?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)佩谣。 經(jīng)常有香客問我把还,道長(zhǎng),這世上最難降的妖魔是什么茸俭? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任吊履,我火速辦了婚禮,結(jié)果婚禮上调鬓,老公的妹妹穿的比我還像新娘艇炎。我一直安慰自己,他們只是感情好腾窝,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布缀踪。 她就那樣靜靜地躺著,像睡著了一般虹脯。 火紅的嫁衣襯著肌膚如雪辜贵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天归形,我揣著相機(jī)與錄音托慨,去河邊找鬼。 笑死暇榴,一個(gè)胖子當(dāng)著我的面吹牛厚棵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔼紧,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼婆硬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了奸例?” 一聲冷哼從身側(cè)響起彬犯,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤向楼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谐区,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體湖蜕,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宋列,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昭抒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炼杖,死狀恐怖灭返,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坤邪,我是刑警寧澤熙含,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站艇纺,受9級(jí)特大地震影響婆芦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喂饥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肠鲫。 院中可真熱鬧员帮,春花似錦、人聲如沸导饲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渣锦。三九已至硝岗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間袋毙,已是汗流浹背型檀。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留听盖,地道東北人胀溺。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像皆看,于是被迫代替她去往敵國和親仓坞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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