JSON和第三方庫
用到的第三方庫:
- ObjectiveC: MJExtension
- swift: Argo
JSON示例:
{
"author": [
{
"id": 6,
"name": "Gob Bluth"
},
{
"id": 7,
"name": "7Gob Bluth"
}
],
"text": "I've made a huge mistake.",
"comments": [
{
"author": {
"id": 1,
"name": "Lucille"
},
"text": "Really? Did 'nothing' cancel?"
}
]
}
JSON轉模型
在OC中,利用MJExtension等第三方庫,我們能夠很方便的將JSON轉換為模型。
在swift中,就沒有這么方便了。因為會有可選值(optional)類型的影響。往往需要判斷是否是可選值,各種右移if let判斷,無法忍受。這里有篇文章 說的很詳細,還有對比當前流行的庫的優缺點。
SWIFT JSON SHOOT-OUT 文章鏈接
在swift中怎么進行JSON轉模型操作呢?
- 橋接ObjectiveC的MJExtension到swift中,進行轉換操作
- 使用swift版本的庫Argo,進行轉換操作
橋接MJExtension到swift
大致步驟如下:
- 創建繼承自NSObject的模型Model,橋接在swift項目里。
- 用ESJsonFormat工具創建類屬性。
- 在swift中,進行轉換。
//獲取JSON數據,然后轉換
let filePath = NSBundle.mainBundle().pathForResource("data", ofType: "json")
let contentData = NSFileManager.defaultManager().contentsAtPath(filePath!)
let content = NSString(data: contentData!, encoding: NSUTF8StringEncoding) as? String
//JSON轉模型
let model = Model.mj_objectWithKeyValues(content)
print(model.ShopList[0].ShopInfo.develiyTime)
使用Argo庫
Argo庫用函數式方法來轉換。不過里面用到了許多操作符,咋看上去簡直嚇死人。不過熟悉后就好了。
像這樣的:
struct Author {
let id: Int
let name: String
}
extension Author: Decodable {
static func decode(json: JSON) -> Decoded<Author.DecodedType> {
return curry(self.init)
<^> json <| "id"
<*> json <| "name"
}
}
使用步驟:
- 創建模型結構體
- 擴展結構體并遵守協議:
Decodable
,實現協議方法decode(json: JSON)
。并映射對應關系。
操作符說明:
“<|” 映射字符值。含義是轉換<|右邊對應的屬性名,屬性名是String的。如:
<^> json <| "id",映射JSON中的id字段為id屬性。
“<|?” 映射可選字符值。就是說轉換過來的值有可能是null
"<^>" map,映射的意思。具體什么用的,不是很了解,不過,一般擴展方法中,它都是第一個。
“<*>” apply和上一個類似。
“<||” 轉換數組。這個是轉換JSON中的數組值用的。如:JSON {"array":["1","2"]} ,轉換的話就是: <|| ["array"]
“<||?” 轉換的數組是可選值,有可能是null.
示例的JSON,用Argo轉換為模型的代碼,看起來有點多。
//SwiftModel.swfit中
import UIKit
import Argo
import Curry
struct Author {
let id: Int
let name: String
}
extension Author: Decodable {
static func decode(json: JSON) -> Decoded<Author.DecodedType> {
return curry(self.init)
<^> json <| "id"
<*> json <| "name"
}
}
struct Comments {
let author: Author
let text: String
}
extension Comments: Decodable {
static func decode(json: JSON) -> Decoded<Comments.DecodedType> {
return curry(self.init)
<^> json <| "author"
<*> json <| "text"
}
}
struct SwiftModel {
let author: [Author]
let text: String
let comments: [Comments]
}
extension SwiftModel: Decodable {
static func decode(json: JSON) -> Decoded<SwiftModel.DecodedType> {
return curry(self.init)
<^> json <|| ["author"]
<*> json <| "text"
<*> json <|| ["comments"]
}
}
//viewController中
let json = JSONFromFile("data")
let argoModel: SwiftModel = json.flatMap(decode)!
print(argoModel.author[0].name)
樣例工程在這里