Swift4.0 Encodable、Decodable


……此处省略一万字

一、UI

界面


二、Encodable 编码

一个最常见的http请求

guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        let postDictionary = ["userId":"87",
                              "id":"787",
                              "title":"你好啊,小明",
                              "body":"给我滚出去"]
        do {
            let jsonBody = try JSONSerialization.data(withJSONObject: postDictionary, options: .prettyPrinted)
            request.httpBody = jsonBody
        } catch {
        }
        
        let session = URLSession.shared
        session.dataTask(with: request) { (data, response, error) in
            guard let data = data else { return }
            do{
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
                print(json)
            }catch{
                print(error)
            }
        }.resume()


下面我们在上面的例子中使用Encodable
  • 1、创建一个结构体,并且继承Encodable
struct Post: Encodable {
    var body: String?
    var title: String?
    var id: Int
    var userId
}
  • 2、然后替换掉上面的HttoBody部分代码
...
   let post = Post(body: "给我滚出去", title: "你好啊,小明", id: 787, userId: 87)
        do {
            let jsonBody = try JSONEncoder().encode(user)
            request.httpBody = jsonBody
        } catch {
        }
...

瞬间解放了自己拼接字典的操作,是不是很舒服?


在上面的请求返回中,我们还是使用的最原始的方法,现在改为用Decodable去做
  • 1、让User这个struct遵从Decodable这个协议
struct Post: Encodable, Decodable {
    var body: String?
    var title: String?
    var id: Int
    var userId: Int
}
  • 2、然后修改为如下代码:
let json = try JSONDecoder().decode(Post.self, from: data)
                print(json)
parse


OK,到了这里你就知道了Encodable、Decodable的基本用法了。
在实际项目开发中,通常返回的数据不会这么简单,很有可能嵌套很多数据,这个时候如何使用Decodable去解析呢?


二、Decodable

先看下我们要解析的数据:


数据

根据上面的json数据,我们定义了如下的结构体

struct User: Decodable {
    var id: Int
    var name: String
    var username: String
    var email: String
    var phone: String
    var website: String
    var company: [String: String]
}

我并没有定义address,因为这个里面还嵌套了一层,后面会写到的。


OK,开始请求数据
      guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { return }
        
        let session = URLSession.shared
        session.dataTask(with: url) { (data, response, error) in
            guard let data = data else { return }
            do{
                //原始解析方法
//                let json = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
//                print(json)
                
                let users = try JSONDecoder().decode([User].self, from: data)
                print(users)
            }catch{
                print(error)
            }
        }.resume()

然后运行,然后……


意外啦
  • 意思就是,得到的数据是一个数组,解码失败啦!!!,如何搞定?



很简单

let users = try JSONDecoder().decode([User].self, from: data)

然后运行效果如下:


解析数据


  • 密密麻麻的数据不便于查看,接下来我们先只打印company
let users = try JSONDecoder().decode([User].self, from: data)
for user in users{
    print(user.company)
}

["catchPhrase": "Multi-layered client-server neural-net", "name": "Romaguera-Crona", "bs": "harness real-time e-markets"]
["catchPhrase": "Proactive didactic contingency", "name": "Deckow-Crist", "bs": "synergize scalable supply-chains"]
["catchPhrase": "Face to face bifurcated interface", "name": "Romaguera-Jacobson", "bs": "e-enable strategic applications"]
["catchPhrase": "Multi-tiered zero tolerance productivity", "name": "Robel-Corkery", "bs": "transition cutting-edge web services"]
["catchPhrase": "User-centric fault-tolerant solution", "name": "Keebler LLC", "bs": "revolutionize end-to-end systems"]
["catchPhrase": "Synchronised bottom-line interface", "name": "Considine-Lockman", "bs": "e-enable innovative applications"]
["catchPhrase": "Configurable multimedia task-force", "name": "Johns Group", "bs": "generate enterprise e-tailers"]
["catchPhrase": "Implemented secondary concept", "name": "Abernathy Group", "bs": "e-enable extensible e-tailers"]
["catchPhrase": "Switchable contextually-based project", "name": "Yost and Sons", "bs": "aggregate real-time technologies"]
["catchPhrase": "Centralized empowering task-force", "name": "Hoeger LLC", "bs": "target end-to-end models"]


这个时候我们发现,我们得到的还不是一个对象,然后我想一步到位把company也给解析出来如何做呢?


  • 很简单,定义一个结构体,然后遵从Decodable协议
struct Company: Decodable {
    var name: String
    var catchPhrase: String
    var bs: String
}

把User的结构体的company重新赋值
var company: Company

//只打印公司名称
 for user in users{
     print(user.company.name)
 }


  • 然后在运行一次,神奇的事情就发生了:
Romaguera-Crona
Deckow-Crist
Romaguera-Jacobson
Robel-Corkery
Keebler LLC
Considine-Lockman
Johns Group
Abernathy Group
Yost and Sons
Hoeger LLC

现在company也可以完成解析,就还剩下多重嵌套的Address还没写了。
通过上面的代码可以知道,可以嵌套解析,所以address就是套娃操作了


  • 1、定义结构体
struct Address: Decodable {
    var street: String
    var suite: String
    var city: String
    var zipcode: String
    var geo: Geo
}

struct Geo: Decodable {
    var lat: String
    var lng: String
}

在User结构体中新增
var address: Address

然后?然后就写完啦,为了测试,我们打印user.address.geo.lat

解析出来啦

OK,到这里基本上就阔以不使用第三方去解析数据啦!!!

Demo 地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容