RxSwift之深入解析URLSession的数据请求和数据处理

Posted Forever_wj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RxSwift之深入解析URLSession的数据请求和数据处理相关的知识,希望对你有一定的参考价值。

一、请求网络数据

① 通过 rx.response 请求数据

  • 如下所示,通过豆瓣提供的音乐频道列表接口获取数据,并将返回结果输出到控制台中:
"https://www.douban.com/j/app/radio/channels" -i -v
Success (2134ms): Status 200
返回的数据是: {"channels":[{"name_en":"Personal Radio","seq_id":0,"abbr_en":"My","name":"私人兆赫","channel_id":0},{"name":"华语","seq_id":0,"abbr_en":"","channel_id":"1","name_en":""},{"name":"欧美","seq_id":1,"abbr_en":"","channel_id":"2","name_en":""},{"name":"七零","seq_id":2,"abbr_en":"","channel_id":"3","name_en":""},{"name":"八零","seq_id":3,"abbr_en":"","channel_id":"4","name_en":""},{"name":"九零","seq_id":4,"abbr_en":"","channel_id":"5","name_en":""},{"name":"粤语","seq_id":5,"abbr_en":"","channel_id":"6","name_en":""},{"name":"摇滚","seq_id":6,"abbr_en":"","channel_id":"7","name_en":""},{"name":"民谣","seq_id":7,"abbr_en":"","channel_id":"8","name_en":""},{"name":"轻音乐","seq_id":8,"abbr_en":"","channel_id":"9","name_en":""},{"name":"原声","seq_id":9,"abbr_en":"","channel_id":"10","name_en":""},{"name":"Fly by midnight ","seq_id":10,"abbr_en":"","channel_id":"267","name_en":""},{"name":"独立","seq_id":11,"abbr_en":"","channel_id":"268","name_en":""},{"name":"爵士","seq_id":12,"abbr_en":"","channel_id":"13","name_en":""},{"name":"电子","seq_id":13,"abbr_en":"","channel_id":"14","name_en":""},{"name":"说唱","seq_id":14,"abbr_en":"","channel_id":"15","name_en":""},{"name":"R&B ","seq_id":15,"abbr_en":"","channel_id":"16","name_en":""},{"name":"日语","seq_id":16,"abbr_en":"","channel_id":"17","name_en":""},{"name":"韩语","seq_id":17,"abbr_en":"","channel_id":"18","name_en":""},{"name":"我的巴比伦恋人","seq_id":18,"abbr_en":"","channel_id":"259","name_en":""},{"name":"女声","seq_id":19,"abbr_en":"","channel_id":"20","name_en":""},{"name":"法语","seq_id":20,"abbr_en":"","channel_id":"22","name_en":""},{"name":"户外","seq_id":21,"abbr_en":"","channel_id":"151","name_en":""},{"name":"休息","seq_id":22,"abbr_en":"","channel_id":"152","name_en":""},{"name":"工作学习","seq_id":23,"abbr_en":"","channel_id":"153","name_en":""},{"name":"亢奋","seq_id":24,"abbr_en":"","channel_id":"154","name_en":""},{"name":"古典","seq_id":25,"abbr_en":"","channel_id":"27","name_en":""},{"name":"动漫","seq_id":26,"abbr_en":"","channel_id":"28","name_en":""},{"name":"咖啡馆","seq_id":27,"abbr_en":"","channel_id":"32","name_en":""},{"name":"舒缓","seq_id":28,"abbr_en":"","channel_id":"155","name_en":""},{"name":"18岁青春的召唤","seq_id":29,"abbr_en":"","channel_id":"262","name_en":""},{"name":"红歌","seq_id":30,"abbr_en":"","channel_id":"41","name_en":""},{"name":"圣诞","seq_id":31,"abbr_en":"","channel_id":"170","name_en":""},{"name":"运动","seq_id":32,"abbr_en":"","channel_id":"257","name_en":""},{"name":"英语","seq_id":33,"abbr_en":"","channel_id":"264","name_en":""},{"name":"豆瓣好歌曲","seq_id":34,"abbr_en":"","channel_id":"179","name_en":""},{"name":"Future Pop","seq_id":35,"abbr_en":"","channel_id":"266","name_en":""},{"name":"金属","seq_id":36,"abbr_en":"","channel_id":"187","name_en":""},{"name":"布鲁斯","seq_id":37,"abbr_en":"","channel_id":"188","name_en":""},{"name":"新歌","seq_id":38,"abbr_en":"","channel_id":"61","name_en":""},{"name":"世界杯","seq_id":39,"abbr_en":"","channel_id":"201","name_en":""},{"name":"朋克","seq_id":40,"abbr_en":"","channel_id":"76","name_en":""},{"name":"Easy ","seq_id":41,"abbr_en":"","channel_id":"77","name_en":""},{"name":"91.1 ","seq_id":42,"abbr_en":"","channel_id":"78","name_en":""},{"name":"乡村","seq_id":43,"abbr_en":"","channel_id":"269","name_en":""},{"name":"“砖”属音乐","seq_id":44,"abbr_en":"","channel_id":"145","name_en":""},{"name":"Pop","seq_id":45,"abbr_en":"","channel_id":"194","name_en":""},{"name":"拉丁","seq_id":46,"abbr_en":"","channel_id":"189","name_en":""}]}
  • 请求示例如下:
// 创建URL对象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
// 创建请求对象
let request = URLRequest(url: url!)
 
// 创建并发起请求
URLSession.shared.rx.response(request: request).subscribe(onNext: {
    (response, data) in
    // 数据处理
    let str = String(data: data, encoding: String.Encoding.utf8)
    print("返回的数据是:", str ?? "")
}).disposed(by: disposeBag)
  • 从以上示例,可以看到,不管请求成功与否都会进入到 onNext 这个回调中,如果需要根据响应状态进行一些相应操作,比如:
    • 状态码在 200 ~ 300 则正常显示数据;
    • 如果是异常状态码(比如:404)则弹出告警提示框。
  • 可以借助 response 参数进行判断即可,把 url 改成一个错误的地址:
// 创建URL对象
let urlString = "https://www.douban.com/xxxxxxxxxx/app/radio/channels"
let url = URL(string:urlString)
// 创建请求对象
let request = URLRequest(url: url!)
 
// 创建并发起请求
URLSession.shared.rx.response(request: request).subscribe(onNext: {
    (response, data) in
    // 判断响应结果状态码
    if 200 ..< 300 ~= response.statusCode {
        let str = String(data: data, encoding: String.Encoding.utf8)
        print("请求成功!返回的数据是:", str ?? "")
    }else{
        print("请求失败!")
    }
}).disposed(by: disposeBag)
  • 运行结果如下:
curl -X GET 
"https://www.douban.com/xxxxxxxxxx/app/radio/channels" -i -v
Failure (1448ms): Status 404
请求失败!

② 通过 rx.data 请求数据

  • rx.data 与 rx.response 的区别:
    • 如果不需要获取底层的 response,只需知道请求是否成功,以及成功时返回的结果,那么建议使用 rx.data。
    • 因为 rx.data 会自动对响应状态码进行判断,只有成功的响应(状态码为 200~300)才会进入到 onNext 这个回调,否则进入 onError 这个回调。
  • 如果不需要考虑请求失败的情况,只对成功返回的结果做处理可以在 onNext 回调中进行相关操作:
// 创建URL对象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
// 创建请求对象
let request = URLRequest(url: url!)
 
// 创建并发起请求
URLSession.shared.rx.data(request: request).subscribe(onNext: {
    data in
    let str = String(data: data, encoding: String.Encoding.utf8)
    print("请求成功!返回的数据是:", str ?? "")
}).disposed(by: disposeBag)
  • 运行结果:
"https://www.douban.com/j/app/radio/channels" -i -v
Success (1449ms): Status 200
请求成功!返回的数据是: {"channels":[{"name_en":"Personal Radio","seq_id":0,"abbr_en":"My","name":"私人兆赫","channel_id":0},{"name":"华语","seq_id":0,"abbr_en":"","channel_id":"1","name_en":""},{"name":"欧美","seq_id":1,"abbr_en":"","channel_id":"2","name_en":""},{"name":"七零","seq_id":2,"abbr_en":"","channel_id":"3","name_en":""},{"name":"八零","seq_id":3,"abbr_en":"","channel_id":"4","name_en":""},{"name":"九零","seq_id":4,"abbr_en":"","channel_id":"5","name_en":""},{"name":"粤语&#

以上是关于RxSwift之深入解析URLSession的数据请求和数据处理的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift之深入解析dispose源码的实现

RxSwift之深入解析核心逻辑Observable的底层原理

RxSwift之深入解析Observable序列的创建

RxSwift之深入解析Using操作的应用和原理

RxSwift之深入解析场景特征序列的使用和底层实现

RxSwift之深入解析map操作符的底层实现