Swift Json解析方法

語意php

序列化:將數據類型和對象轉換成二進制數據json

反序列化:將返回的二進制數據轉換成對象和其它數據結構swift


handyJSON

比較好用的JSON轉義Model,使用中幫咱們把數據轉成完成class、struct數組

**反序列化
//1.聲明一個model,繼承HandyJSON協議 (枚舉繼承 HandyJSONEnum協議)
//嵌套:遇到複雜的狀況model嵌套model 只須要繼承HandyHSON就能夠
//繼承:只須要父類繼承HandyJSON就能夠
class Model: HandyJSON {
    var int: Int = 2
    var doubleOptional: Double?
    var stringImplicitlyUnwrapped: String!

    required init() {}//若是是class類型,須要加入這一步,否則會報錯
}
//2. jsonString 傳入須要反序列化的數據
// 得到某個個結點的數據結構 用這個方法:designatedPath
if let animal = Model.deserialize(from: jsonString) {
    print(animal)//結果是model類型,須要用點語法得到屬性值
}複製代碼

**序列化
//1.聲明一個model,繼承HandyJSON協議
class Bob: HandyJSON {
     required init() {}
     var int: Int = 30
     var fou: Double?
     var strinfmp: String?
     }
     //2.生成對應的model對象
     let obje = Bob()
     obje.int = 1
     obje.fou = 1.1
     obje.strinfmp = "hello"
     //3.點語法方法,序列化   
     print(obje.toJSON()!) // dictionary(字典)
     print(obje.toJSONString()!) // JSON string(JSON)
     print(obje.toJSONString(prettyPrint: true)!) // pretty JSON string (映射json字符串)複製代碼

**自定義(適用於更改model內屬性的名稱,解析麻煩的數據結構,如元祖類型數據)
//1.聲明一個model,繼承HandyJSON協議
class Cat: HandyJSON {
    var id: Int64!
    var name: String!
    var parent: (String, String)?

    required init() {}
	
	//2.實現函數 mapping方法
    func mapping(mapper: HelpingMapper) {
        //3. 使用specify(property:)自定義字段內容
        mapper.specify(property: &id, name: "cat_id")
        mapper.specify(property: &parent) { (rawString) -> (String, String) in
            let parentNames = rawString.characters.split{$0 == "/"}.map(String.init)
            return (parentNames[0], parentNames[1])
        }
    }
}複製代碼

問:爲何 mapping函數在繼承的子類裏很差使?
答:由於Swift類型相關的緣由,若是須要在子類裏使用mapping函數,那麼必須在父類(若是有多層父類,必須在最頂層的父類)裏定義一個空的mapping函數,而後在子類去override它。同樣狀況的還有didFinishMapping函數。

swiftyJSON

方便的獲取節點層面的信息,不用擔憂數組越界並自動對可選類型進行拆包。
bash

**反序列化
(解析本地JSON)
//JSON 轉 Data
let data = "{\"doubleOptional\":1.1,\"stringImplicitlyUnwrapped\":\"hello\",\"int\":1}"
if let dataFromString = data.data(using: .utf8, allowLossyConversion: false) {
	let json = try! JSON(data: dataFromString)
	//獲取全部字段的的鍵值
	for (index,obj) in json {
        print("\(index) : \(obj)")
    }
	//獲取指定字段頭的value
	if let dou = json["stringImplicitlyUnwrapped"].string {
		print("data \(dou)")
	}else {
		//打印錯誤信息
	}
}
複製代碼

**序列化

//簡單數據類型
let json: JSON = "I'm a son"

//Array & Dictionary
var json: JSON =  ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]]
json["list"][3]["what"] = "that"
json["list",3,"what"] = "that"
let path:[JSONSubscriptType] = ["list",3,"what"]
json[path] = "that"複製代碼

(獲取網絡URL解析數據)
//建立URL對象
let url = URL(string:"http://www.hangge.com/getJsonData.php")!
// Alamofire框架 
Alamofire.request(url).validate().responseJSON { response in
    switch response.result.isSuccess {
    case true:
        if let value = response.result.value {
            let json = JSON(value)
            if let number = json[0]["phones"][0]["number"].string {
                // 找到電話號碼
                print("第一個聯繫人的第一個電話號碼:",number)
            }
        }
    case false:
        print(response.result.error)
    }
}複製代碼

Codable(原生)

Apple 在 Swift 4 的 Foundation 的模塊中添加了對 JSON 解析成Model的原生支持。
網絡

關於 Codable 同時聲明瞭 Decodable 和 Encodable 兩個協議,只須要單向處理能夠只聲明一個。
/// A type that can convert itself into and out of an external representation.
public typealias Codable = Decodable & Encodable複製代碼
須要知足Codable協議。
須要JSON數據結構和Model對象結構同樣,任何差異都會致使解析式失敗。

**自定義鍵值名
struct UserList: Codable {
    let userInfos: [UserInfo]
    
    struct UserInfo: Codable {
        let userName: String
        let age: Int
        let bodyHeight: Float
        let sex: Bool
        
        private enum CodingKeys: String, CodingKey {
            case userName
            case age
            case bodyHeight = "height"
            case sex
        }
    }
}複製代碼

**格式處理
包括屬性和方法,可根據本身的須要設置想要的格式。

// outputFormatting屬性,提升閱讀體驗
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted複製代碼

**定義可選值
若是JSON的數據結構中,有些 Key - Value 不必定出現,Model中對應的要使用可選類型
例子:
(json)
{
    "userInfos": [
        {
            "userName": "小名",
            "age": 18,
            "sex": true
        },
        {
            "userName": "小方",
            "age": 18,
            "height": 162.56,
            "sex": false
        }
    ]
}
(model)
struct UserList: Codable {

    let userInfos: [UserInfo]

    struct UserInfo: Codable {

        let userName: String
        let age: Int
  	 	let height: Float?(可選)
        let sex: Bool
    }
}複製代碼


好久不寫swift有些生疏了,最近我也在回顧有關swift的代碼,同時也一直在思考swift該如何寫,才能駕輕就熟,才能更像一個優雅的工具,由於會用和用好它差異仍是挺大的,會一直不斷探索iOS的更多有趣性。加油吧!
數據結構

相關文章
相關標籤/搜索