json是移動端開發常用的應用層資料交換協議。最常見的場景便是,客戶端向服務端發起網路請求,服務端返回json文字,然後客戶端解析這個json文字,再把對應資料展現到頁面上。
但在程式設計的時候,處理json是一件麻煩事。在不引入任何輪子的情況下,我們通常需要先把json轉為dictionary,然後還要記住每個資料對應的key,用這個key在dictionary中取出對應的value來使用。這個過程我們會犯各種錯誤:
* key拼寫錯了
* 路徑寫錯了
* 型別搞錯了
* 沒拿到值懵逼了
* 某一天和服務端約定的某個字段變更了,沒能更新所有用到它的地方
* ...
為了解決這些問題,很多處理json的開源庫應運而生。在swift中,這些開源庫主要朝著兩個方向努力:
1. 保持json語義,直接解析json,但通過封裝使呼叫方式更優雅、更安全
2. 預定義model類,將json反序列化為類例項,再使用這些例項
對於1,使用最廣、評價最好的庫非 swiftyjson 莫屬,它很能代表這個方向的核心。它本質上仍然是根據json結構去取值,使用起來順手、清晰。但也正因如此,這種做法沒能妥善解決上述的幾個問題,因為key、路徑、型別仍然需要開發者去指定;
今天我們先來看看swiftyjson的用法。
//轉成json物件
let jsondata = json.init(data)
不管需要什麼資料只要通過對jsondata
進行路徑讀取
例如:
let build_name = jsondata[0]["build_name"].strin**alue
值得一提的是,不需要考慮伺服器給我們返回的是什麼型別,比如去請求乙個房屋的棟數"build_num": 588
我們想要獲得int型別或者string型別都可以
let room_num1 = jsondata[0]["build_num"].strin**alue
let room_num2 = jsondata[0]["build_num"].intvalue
// room_num1 = 588 string型別
// room_num2 = 588 int型別
這樣通過.strin**alue
.intvalue
就可以獲得不可選值型別,如果沒有獲取到資料的話就會返回乙個預設值即.strin**alue
獲得空字串""
,.intvalue
得到0
,.arrayvalue
獲得空陣列,我們就不用判斷拆包了。
當然某些場景可能需要你得到可選值型別並自己判斷是否存在,那麼我們可以通過.string .int .bool .float .array .dictionary
等等方法獲取,例如:
//string
if let build_name = jsondata[0]["build_name"].string else
解析資料是真的非常簡單。詳細使用可以看看swiftyjson的使用詳解(附樣例)
或者移步github-swiftyjson
但是對於專案而言我們需要對資料進行轉換為模型,僅僅是對data進行json讀取是遠遠不夠的,想想,如果遇到許多地方都用到了build_name
值,但是當伺服器給我們返回的欄位名字改了,我們改專案時就會顯得麻煩,甚至造成改不完全,所以我們隊資料封裝一下轉為模型,這樣修改時只用改乙個地方就是model的賦值就好了。
那我的方法是:
//這是模擬資料
let baseinfo: [string : any] = ["build_name":"置信·原墅",
"build_address":"學院中路與金橋路交匯處東北側",
"build_num": 12,
"room_num": 588,
"area_address":"浙江省溫州市鹿城區五馬街道"]
建立struct模型,當然class也可以,但是如果不需要繼承也不複雜推薦struct(-。-不多解釋了)
並寫好建立方法
import swiftyjson
struct buildbaseinfomodel
}
呼叫:
let jsondata = json(baseinfo)
let model = buildbaseinfomodel.init(jsondata: jsondata)
// 會得到建立好的 buildbaseinfomodel型別的 物件model
// 也可以這樣寫
let model = buildbaseinfomodel(jsondata: jsondata)
當然這只是普通的模型,經常會遇到複雜模型,例如:
// 面積中89是int, 109和129是string
let baseinfo: [string : any] = ["build_name":"置信·原墅",
"build_address":"學院中路與金橋路交匯處東北側",
"area_address":"浙江省溫州市鹿城區五馬街道",
"area":[89,"109","129"],
"detail_address":["province":"浙江省",
"city":"溫州市",
"district":"鹿城區",
"street":"五馬街道"],
"build_num": 12,
"room_num": 588]
這時候模型就應該有兩個
struct buildbaseinfomodel
}
struct detailaddressmodel
}
let model = buildbaseinfomodel(jsondata: jsondata)
dprint(message: model.detail_address.city)
dprint(message: model.area?.first)
dprint(message: model.area?[1])
// *********.swift[21], updateroomsdata(index:): optional("溫州市")
// *********.swift[22], updateroomsdata(index:): optional(89)
// *********.swift[22], updateroomsdata(index:): optional("109")
SwiftyJSON的簡單使用
初始化 let json json data datafromnetworking 這裡的object是anyobject,但是必須是能轉會成json的資料型別。傳錯也沒關係,最多你後面再也取不到資料了。let json json jsonobject subscript 下標?從乙個假定對應的是陣...
使用SwiftyJSON解析JSON
因為swift對於型別有非常嚴格的控制,它在處理json時是挺麻煩的,因為它天生就是隱式型別。swiftyjson是乙個能幫助我們在swift中使用json的開源類庫。開始之前,讓我們先看一下在swift中處理json是多麼痛苦。下面將解析這個json資料。swiftyjson 獲取json var...
SwiftyJson 的初步理解
最初的認識 swiftyjson 的本質就是乙個 public struct json結構體 struct json 的構成 public struct json public static varnull json object in json 這個是核心的屬性 所有的操作就是 在這給個地方開始的...