生活随笔
收集整理的這篇文章主要介紹了
RxSwift之深入解析URLSession的数据请求和数据处理
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)
① 通過(guò) rx.response 請(qǐng)求數(shù)據(jù)
- 如下所示,通過(guò)豆瓣提供的音樂(lè)頻道列表接口獲取數(shù)據(jù),并將返回結(jié)果輸出到控制臺(tái)中:
"https://www.douban.com/j/app/radio/channels" -i
-v
Success (2134ms
): Status 200
返回的數(shù)據(jù)是:
{"channels":[{"name_en":"Personal Radio","seq_id":0,"abbr_en":"My","name":"私人兆赫","channel_id":0},{"name":"華語(yǔ)","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":"粵語(yǔ)","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":"輕音樂(lè)","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":"獨(dú)立","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":"說(shuō)唱","seq_id":14,"abbr_en":"","channel_id":"15","name_en":""},{"name":"R&B ","seq_id":15,"abbr_en":"","channel_id":"16","name_en":""},{"name":"日語(yǔ)","seq_id":16,"abbr_en":"","channel_id":"17","name_en":""},{"name":"韓語(yǔ)","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":"法語(yǔ)","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":"工作學(xué)習(xí)","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":"動(dòng)漫","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":"運(yùn)動(dòng)","seq_id":32,"abbr_en":"","channel_id":"257","name_en":""},{"name":"英語(yǔ)","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":"鄉(xiāng)村","seq_id":43,"abbr_en":"","channel_id":"269","name_en":""},{"name":"“磚”屬音樂(lè)","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":""}]}
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
) inlet str
= String(data
: data
, encoding
: String.Encoding.utf8
)print("返回的數(shù)據(jù)是:", str
?? "")
}).disposed(by
: disposeBag
)
- 從以上示例,可以看到,不管請(qǐng)求成功與否都會(huì)進(jìn)入到 onNext 這個(gè)回調(diào)中,如果需要根據(jù)響應(yīng)狀態(tài)進(jìn)行一些相應(yīng)操作,比如:
-
- 狀態(tài)碼在 200 ~ 300 則正常顯示數(shù)據(jù);
-
- 如果是異常狀態(tài)碼(比如:404)則彈出告警提示框。
- 可以借助 response 參數(shù)進(jìn)行判斷即可,把 url 改成一個(gè)錯(cuò)誤的地址:
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
) inif 200 ..< 300 ~= response
.statusCode
{let str
= String(data
: data
, encoding
: String.Encoding.utf8
)print("請(qǐng)求成功!返回的數(shù)據(jù)是:", str
?? "")}else{print("請(qǐng)求失敗!")}
}).disposed(by
: disposeBag
)
curl
-X
GET
"https://www.douban.com/xxxxxxxxxx/app/radio/channels" -i
-v
Failure (1448ms
): Status 404
請(qǐng)求失敗!
② 通過(guò) rx.data 請(qǐng)求數(shù)據(jù)
- rx.data 與 rx.response 的區(qū)別:
-
- 如果不需要獲取底層的 response,只需知道請(qǐng)求是否成功,以及成功時(shí)返回的結(jié)果,那么建議使用 rx.data。
-
- 因?yàn)?rx.data 會(huì)自動(dòng)對(duì)響應(yīng)狀態(tài)碼進(jìn)行判斷,只有成功的響應(yīng)(狀態(tài)碼為 200~300)才會(huì)進(jìn)入到 onNext 這個(gè)回調(diào),否則進(jìn)入 onError 這個(gè)回調(diào)。
- 如果不需要考慮請(qǐng)求失敗的情況,只對(duì)成功返回的結(jié)果做處理可以在 onNext 回調(diào)中進(jìn)行相關(guān)操作:
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
inlet str
= String(data
: data
, encoding
: String.Encoding.utf8
)print("請(qǐng)求成功!返回的數(shù)據(jù)是:", str
?? "")
}).disposed(by
: disposeBag
)
"https://www.douban.com/j/app/radio/channels" -i
-v
Success (1449ms
): Status 200
請(qǐng)求成功!返回的數(shù)據(jù)是:
{"channels":[{"name_en":"Personal Radio","seq_id":0,"abbr_en":"My","name":"私人兆赫","channel_id":0},{"name":"華語(yǔ)","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":"粵語(yǔ)","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":"輕音樂(lè)","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":"獨(dú)立","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":"說(shuō)唱","seq_id":14,"abbr_en":"","channel_id":"15","name_en":""},{"name":"R&B ","seq_id":15,"abbr_en":"","channel_id":"16","name_en":""},{"name":"日語(yǔ)","seq_id":16,"abbr_en":"","channel_id":"17","name_en":""},{"name":"韓語(yǔ)","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":"法語(yǔ)","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":"工作學(xué)習(xí)","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":"動(dòng)漫","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":"運(yùn)動(dòng)","seq_id":32,"abbr_en":"","channel_id":"257","name_en":""},{"name":"英語(yǔ)","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":"鄉(xiāng)村","seq_id":43,"abbr_en":"","channel_id":"269","name_en":""},{"name":"“磚”屬音樂(lè)","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":""}]}
- 如果還要處理失敗的情況,可以在 onError 回調(diào)中操作:
let urlString
= "https://www.douban.com/xxxxxx/app/radio/channels"
let url
= URL(string
:urlString
)
let request
= URLRequest(url
: url
!)
URLSession.shared
.rx
.data(request
: request
).subscribe(onNext
: {data
inlet str
= String(data
: data
, encoding
: String.Encoding.utf8
)print("請(qǐng)求成功!返回的數(shù)據(jù)是:", str
?? "")
}, onError
: { error
inprint("請(qǐng)求失敗!錯(cuò)誤原因:", error
)
}).disposed(by
: disposeBag
)
"https://www.douban.com/xxxxxx/app/radio/channels" -i
-v
Failure (7189ms
): Status 404
請(qǐng)求失敗!錯(cuò)誤原因:
HTTP request failed with `
404`
.
二、手動(dòng)發(fā)起請(qǐng)求和取消請(qǐng)求
- 在很多情況下,網(wǎng)絡(luò)請(qǐng)求并不是由程序自動(dòng)發(fā)起的,可能需要我們點(diǎn)擊個(gè)按鈕,或者切換個(gè)標(biāo)簽時(shí)才去請(qǐng)求數(shù)據(jù)。除了手動(dòng)發(fā)起請(qǐng)求外,同樣的可能還需要手動(dòng)取消上一次的網(wǎng)絡(luò)請(qǐng)求(如果未完成),那么 RxSwift 該如何實(shí)現(xiàn)呢?
- 如下所示:
-
- 每次點(diǎn)擊“發(fā)起請(qǐng)求”按鈕則去請(qǐng)求一次數(shù)據(jù);
-
- 如果請(qǐng)求沒(méi)返回時(shí),點(diǎn)擊“取消請(qǐng)求”則可將其取消(取消后即使返回?cái)?shù)據(jù)也不作處理)。
@IBOutlet weak var startBtn
: UIButton!@IBOutlet weak var cancelBtn
: UIButton!let disposeBag
= DisposeBag()override func viewDidLoad() {super.viewDidLoad()let urlString
= "https://www.douban.com/j/app/radio/channels"let url
= URL(string
:urlString
)let request
= URLRequest(url
: url
!)startBtn
.rx
.tap
.asObservable().flatMap
{URLSession.shared
.rx
.data(request
: request
).takeUntil(self.cancelBtn
.rx
.tap
) }.subscribe(onNext
: {data
inlet str
= String(data
: data
, encoding
: String.Encoding.utf8
)print("請(qǐng)求成功!返回的數(shù)據(jù)是:", str
?? "")}, onError
: { error
inprint("請(qǐng)求失敗!錯(cuò)誤原因:", error
)}).disposed(by
: disposeBag
)
三、將結(jié)果轉(zhuǎn)為 Json 對(duì)象
- 如果服務(wù)器返回的數(shù)據(jù)是 json 格式的話,可以使用 iOS 內(nèi)置的 JSONSerialization 將其轉(zhuǎn)成 JSON 對(duì)象,方便使用:
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
inlet json
= try? (JSONSerialization.jsonObject(with
: data
, options
: .allowFragments
)as! [String: Any])print("--- 請(qǐng)求成功,返回的如下數(shù)據(jù) ---")print(json
!)
}).disposed(by
: disposeBag
)
"https://www.douban.com/j/app/radio/channels" -i
-v
Success (3410ms
): Status 200
--- 請(qǐng)求成功!返回的如下數(shù)據(jù)
---
["channels": <__NSArrayI
0x7ff0f2f07080>(
{"abbr_en" = "";"channel_id" = 9;name
= "\U8f7b\U97f3\U4e50";"name_en" = "";"seq_id" = 8;
},
{"abbr_en" = "";"channel_id" = 10;name
= "\U539f\U58f0";"name_en" = "";"seq_id" = 9;
},
{"abbr_en" = "";"channel_id" = 267;name
= "Fly by midnight ";"name_en" = "";"seq_id" = 10;
},
{"abbr_en" = "";"channel_id" = 268;name
= "\U72ec\U7acb";"name_en" = "";"seq_id" = 11;
},
{"abbr_en" = "";"channel_id" = 13;name
= "\U7235\U58eb";"name_en" = "";"seq_id" = 12;
},
{"abbr_en" = "";"channel_id" = 14;name
= "\U7535\U5b50";"name_en" = "";"seq_id" = 13;
},
{"abbr_en" = "";"channel_id" = 15;name
= "\U8bf4\U5531";"name_en" = "";"seq_id" = 14;
},
{"abbr_en" = "";"channel_id" = 16;name
= "R&B ";"name_en" = "";"seq_id" = 15;
},
{"abbr_en" = "";"channel_id" = 17;name
= "\U65e5\U8bed";"name_en" = "";"seq_id" = 16;
},
{"abbr_en" = "";"channel_id" = 18;name
= "\U97e9\U8bed";"name_en" = "";"seq_id" = 17;
},
{"abbr_en" = "";"channel_id" = 259;name
= "\U6211\U7684\U5df4\U6bd4\U4f26\U604b\U4eba";"name_en" = "";"seq_id" = 18;
},
{"abbr_en" = "";"channel_id" = 20;name
= "\U5973\U58f0";"name_en" = "";"seq_id" = 19;
},
{"abbr_en" = "";"channel_id" = 22;name
= "\U6cd5\U8bed";"name_en" = "";"seq_id" = 20;
},
{"abbr_en" = "";"channel_id" = 151;name
= "\U6237\U5916";"name_en" = "";"seq_id" = 21;
},
{"abbr_en" = "";"channel_id" = 152;name
= "\U4f11\U606f";"name_en" = "";"seq_id" = 22;
},
{"abbr_en" = "";"channel_id" = 28;name
= "\U52a8\U6f2b";"name_en" = "";"seq_id" = 26;
},
{"abbr_en" = "";"channel_id" = 32;name
= "\U5496\U5561\U9986";"name_en" = "";"seq_id" = 27;
},
{"abbr_en" = "";"channel_id" = 155;name
= "\U8212\U7f13";"name_en" = "";"seq_id" = 28;
},
{"abbr_en" = "";"channel_id" = 262;name
= "18\U5c81\U9752\U6625\U7684\U53ec\U5524";"name_en" = "";"seq_id" = 29;
},
{"abbr_en" = "";"channel_id" = 41;name
= "\U7ea2\U6b4c";"name_en" = "";"seq_id" = 30;
},
{"abbr_en" = "";"channel_id" = 170;name
= "\U5723\U8bde";"name_en" = "";"seq_id" = 31;
},
{"abbr_en" = "";"channel_id" = 257;name
= "\U8fd0\U52a8";"name_en" = "";"seq_id" = 32;
},
{"abbr_en" = "";"channel_id" = 264;name
= "\U82f1\U8bed";"name_en" = "";"seq_id" = 33;
},
{"abbr_en" = "";"channel_id" = 179;name
= "\U8c46\U74e3\U597d\U6b4c\U66f2";"name_en" = "";"seq_id" = 34;
}
)
]
- 也可以在訂閱前就進(jìn)行轉(zhuǎn)換:
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
).map {try JSONSerialization.jsonObject(with
: $
0, options
: .allowFragments
)as! [String: Any]}.subscribe(onNext
: {data
inprint("--- 請(qǐng)求成功!返回的如下數(shù)據(jù) ---")print(data
)}).disposed(by
: disposeBag
)
- 還有更簡(jiǎn)單的方法,就是直接使用 RxSwift 提供的 rx.json 方法去獲取數(shù)據(jù),它會(huì)直接將結(jié)果轉(zhuǎn)成 Json 對(duì)象:
let urlString
= "https://www.douban.com/j/app/radio/channels"
let url
= URL(string
:urlString
)
let request
= URLRequest(url
: url
!)
URLSession.shared
.rx
.json(request
: request
).subscribe(onNext
: {data
inlet json
= data
as! [String: Any]print("--- 請(qǐng)求成功!返回的如下數(shù)據(jù) ---")print(json
)
}).disposed(by
: disposeBag
)
- 將獲取到的豆瓣頻道列表數(shù)據(jù)轉(zhuǎn)換成 Json 對(duì)象,并綁定到表格上顯示:
self.tableView
= UITableView(frame
: self.view
.frame
, style
:.plain
)
self.tableView
!.register(UITableViewCell.self, forCellReuseIdentifier
: "Cell")
self.view
.addSubview(self.tableView
!)
let urlString
= "https://www.douban.com/j/app/radio/channels"
let url
= URL(string
:urlString
)
let request
= URLRequest(url
: url
!)
let data
= URLSession.shared
.rx
.json(request
: request
).map{ result
-> [[String: Any]] inif let data
= result
as? [String: Any],let channels
= data
["channels"] as? [[String: Any]] {return channels
}else{return []}
}
data
.bind(to
: tableView
.rx
.items
) { (tableView
, row
, element
) inlet cell
= tableView
.dequeueReusableCell(withIdentifier
: "Cell")!cell
.textLabel
?.text
= "\(row):\(element["name"]!)"return cell
}.disposed(by
: disposeBag
)
四、將結(jié)果映射成自定義對(duì)象
① 準(zhǔn)備工作
- 要實(shí)現(xiàn)數(shù)據(jù)到模型(model)的轉(zhuǎn)換,首先需要引入一個(gè)第三方的數(shù)據(jù)模型轉(zhuǎn)換框架:ObjectMapper。
- 為了讓 ObjectMapper 能夠更好地與 RxSwift 配合使用,對(duì) Observable 進(jìn)行擴(kuò)展(RxObjectMapper.swift),增加數(shù)據(jù)轉(zhuǎn)模型對(duì)象、以及數(shù)據(jù)轉(zhuǎn)模型對(duì)象數(shù)組這兩個(gè)方法:
import ObjectMapper
import RxSwift
public enum RxObjectMapperError: Error {case parsingError
}
public extension Observable where Element:Any {public func mapObject
< T
>(type
:T
.Type) -> Observable<T
> where T
:Mappable {let mapper
= Mapper<T
>()return self.map { (element
) -> T
inguard let parsedElement
= mapper
.map(JSONObject: element
) else {throw RxObjectMapperError.parsingError
}return parsedElement
}}public func mapArray
< T
>(type
:T
.Type) -> Observable<[T
]> where T
:Mappable {let mapper
= Mapper<T
>()return self.map { (element
) -> [T
] inguard let parsedArray
= mapper
.mapArray(JSONObject: element
) else {throw RxObjectMapperError.parsingError
}return parsedArray
}}
}
② 使用示例
- 以豆瓣音樂(lè)頻道數(shù)據(jù)為例,首先定義好相關(guān)模型(需要實(shí)現(xiàn) ObjectMapper 的 Mappable 協(xié)議,并設(shè)置好成員對(duì)象與 Json 屬性的相互映射關(guān)系):
class Douban: Mappable {var channels
: [Channel]?init(){}required init?(map: Map) {}func mapping(map: Map) {channels
<- map["channels"]}
}
class Channel: Mappable {var name
: String?var nameEn
:String?var channelId
: String?var seqId
: Int?var abbrEn
: String?init(){}required init?(map: Map) {}func mapping(map: Map) {name
<- map["name"]nameEn
<- map["name_en"]channelId
<- map["channel_id"]seqId
<- map["seq_id"]abbrEn
<- map["abbr_en"]}
}
- 如下所示,獲取數(shù)據(jù),并轉(zhuǎn)換成對(duì)應(yīng)的模型:
let urlString
= "https://www.douban.com/j/app/radio/channels"
let url
= URL(string
:urlString
)
let request
= URLRequest(url
: url
!)
URLSession.shared
.rx
.json(request
: request
).mapObject(type
: Douban.self).subscribe(onNext
: { (douban
: Douban) inif let channels
= douban
.channels
{print("--- 共\(channels.count)個(gè)頻道 ---")for channel
in channels
{if let name
= channel
.name
, let channelId
= channel
.channelId
{print("\(name) (id:\(channelId))")}}}}).disposed(by
: disposeBag
)
- 如下所示,將數(shù)據(jù)換成模型,并綁定到表格上顯示:
self.tableView
= UITableView(frame
: self.view
.frame
, style
:.plain
)
self.tableView
!.register(UITableViewCell.self, forCellReuseIdentifier
: "Cell")
self.view
.addSubview(self.tableView
!)
let urlString
= "https://www.douban.com/j/app/radio/channels"
let url
= URL(string
:urlString
)
let request
= URLRequest(url
: url
!)
let data
= URLSession.shared
.rx
.json(request
: request
).mapObject(type
: Douban.self).map{ $
0.channels
?? []}
data
.bind(to
: tableView
.rx
.items
) { (tableView
, row
, element
) inlet cell
= tableView
.dequeueReusableCell(withIdentifier
: "Cell")!cell
.textLabel
?.text
= "\(row):\(element.name!)"return cell
}.disposed(by
: disposeBag
)
總結(jié)
以上是生活随笔為你收集整理的RxSwift之深入解析URLSession的数据请求和数据处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。