平時寫小專案時請求json格式的資料,怎麼解析向來是乙個大問題,尤其碰到巢狀型的資料,更是不知道怎麼寫**才好,所以寫一篇教程來記錄一下。剛好好久也沒寫部落格了,趕快寫一篇來刷刷存在感…
json是乙個以文字為主、輕量型,並且容易使用來儲存以及交換資料的方式。它通常用來呈現結構性的資料,許多我每天使用的網頁服務都是以json格式為主的api。一句話概括,乙個
json物件
,就是乙個個的
對的集合({}
)。
}
在這個例子中,最外層的{}
包含了4個key
,分別是name
、age
、hobby
、location
,它們都是string
型別;而它們對應value
的型別分別是string
、int
、[string]
、json物件
。我們發現,key
的型別一定是string
即字串,而value
的型別是任意的。
正是因為value
的型別可以是任何型別,如果value
是json物件
,這意味著出現了巢狀,如location
對應的value
就是乙個巢狀在json物件
裡的json物件
,這為我們解析json資料增加了複雜度。上面的例子可以用下面的結構圖表示:
|-- top
|-- "name" ->
"seekingmini"
|-- "age" -> 21
|-- "hobby" ->
["swimming", "coding"
]|-- "location"
|-- "country" ->
"china"
|-- "city" ->
"suzhou"
把它旋轉90度來看,其實就是乙個n叉樹。根結點忽略不計,其他的非葉子結點都是key
,而葉子結點都是value
。當然了,如果沒有巢狀,那麼這棵樹只有3層,頂層是top
,表示最外層的大括號;第2層是key
;第3層是value
。
但是出現了巢狀,location
的子樹就是它的value
,而這棵子樹自身是乙個json
物件,它的葉子結點就是非json
物件型別的value
。
還是不清楚什麼是json的話,就參考菜鳥教程吧!我們的重頭戲放在如何解析包含巢狀的json資料。
解析乙個json格式的資料,最重要的是什麼?我認為應該是結構層次。我們只有定義了準確的結構層次,才能在每一層解析出正確的資料。1) 無腦
struct
疊加
還是以上面的資料為例,我們可以定義出這樣的結構體:
struct
person
:codable
extension
person
}
稍微說明一下:person
這個結構體就代表了整個json物件
的結構。而person
中的每個屬性代表key
;屬性值代表value
。由於存在巢狀,所以location
這個key
的value
需要重新定義乙個結構體location
。這樣的話就能解析了。解析**如下:
// json data
let jsondata =
"""}
"""// parse
iflet data = jsondata.
data
(using:
.utf8)
}// 列印結果如下:
// person(name: "seekingmini", age: 21, hobby: ["swimming", "coding"], location: // __lldb_expr_45.person.location(country: "china", city: "suzhou"))
// seekingmini
// 21
// ["swimming", "coding"]
// china
// suzhou
struct
的疊加非常簡單粗暴,但是會有問題,比如說我的結構體定義成這樣:
struct
person
:codable
那麼location
這個key是解析不出來的,更別提country
和city
了。我們應該怎麼辦呢?
2) 使用enum
和codingkey
協議
利用enum
定義json物件的結構:
enum
codingkeys
:string
,codingkey
}
name
、age
、hobby
和location
這4個key
在同一層,而country
、city
在下一層。每一層就是乙個enum
。通過這樣的定義,我們可以寫出以下的**來解析:
init
(from decoder:
decoder
)throws
從decoder
使用container(keyedby:)
獲取頂級容器後, 我們可以重複使用這些方法:
完整**如下:
import
foundation
// json data
let jsondata =
"""}
"""struct
person
extension
person
:decodable
}init
(from decoder:
decoder
)throws
}// parse
iflet data = jsondata.
data
(using:
.utf8)
}// 列印結果
// person(name: "seekingmini", age: 21, hobby: ["swimming", "coding"], country: "china", city: "suzhou")
使用enum
和codingkey
協議有乙個好處:對於struct
的定義不用考慮json物件
的結構,而json物件
的結構都是通過enum
的巢狀來定義的。參考
如何使用swift decodable協議解碼巢狀的json結構?
Swift解析JSON資料
從ios開發的角度來說,json更多的可以看作是一種包含很多鍵值對的物件。首先我從www.k780.com這個 中得到乙個實時天氣情況介面。這樣顯得清晰多了。那麼如何在swift工程裡對這個url進行解析呢?對json解析,我們需要用到nsjsonserialization。我現在用的是xcode7...
swift 解析取得json中的資料
搞了兩天解析返回的json資料終於出來了,下面就方向給大家 用到了第三的類庫 swifthttp 做request get post put 等 swiftjson 講返回的資料解析為json 下面說一下關鍵 接受返回得來的資料轉為json var ggg json nsjsonserializat...
IOS中JSON資料解析
官方為我們提供的解析json資料的類是 nsjsonserialization,首先我們先來看下這個類的幾個方法 bool isvalidjsonobject id obj 判斷乙個資料物件是否可以轉化為json資料 nsdata datawithjsonobject id obj options ...