語意php
序列化:將數據類型和對象轉換成二進制數據json
反序列化:將返回的二進制數據轉換成對象和其它數據結構swift
比較好用的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
函數在繼承的子類裏很差使?
方便的獲取節點層面的信息,不用擔憂數組越界並自動對可選類型進行拆包。
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)
}
}複製代碼
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的更多有趣性。加油吧!
數據結構