? ? ? ? 在之前的兩篇文章中列吼,我介紹了 RxSwift
對(duì) URLSession
的擴(kuò)展以及使用陨倡。當(dāng)然除了可以使用 URLSession
進(jìn)行網(wǎng)絡(luò)請求外芥牌,網(wǎng)上還有許多優(yōu)秀的第三方網(wǎng)絡(luò)庫也可以與 RxSwift
結(jié)合使用的祭陷,比如:RxAlamofire
和 Moya
。這次我先介紹下前者徒扶。
一 粮彤、安裝配置
1,引入 Alamofire
由于 RxAlamofire
是對(duì) Alamofire
的封裝姜骡,所以我們項(xiàng)目中先要把 Alamofire
庫給引入進(jìn)來导坟。關(guān)于 Alamofire
的安裝配置可以參考航哥之前的文章:
2溶浴,添加 RxAlamofire
(1)這里我使用手動(dòng)配置的方式乍迄,先把 RxAlamofire
庫下載到本地。
(2)接著把里面的 RxAlamofire.swift
文件添加到我們的項(xiàng)目中即可士败。
二、基本用法
1褥伴,使用 request 請求數(shù)據(jù)
(1)下面代碼我們通過豆瓣提供的頻道列表接口獲取數(shù)據(jù)谅将,并將返回結(jié)果輸出到控制臺(tái)中。
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
request(.get, url)
.data()
.subscribe(onNext: {
data in
//數(shù)據(jù)處理
let str = String(data: data, encoding: String.Encoding.utf8)
print("返回的數(shù)據(jù)是:", str ?? "")
}).disposed(by: disposeBag)
(2)如果還要處理失敗的情況重慢,可以在 onError
回調(diào)中操作饥臂。我們把 url
改成一個(gè)錯(cuò)誤的地址,運(yùn)行結(jié)果如下:
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/jxxxxxxxx/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
request(.get, url)
.data()
.subscribe(onNext: {
data in
//數(shù)據(jù)處理
let str = String(data: data, encoding: String.Encoding.utf8)
print("返回的數(shù)據(jù)是:", str ?? "")
}, onError: { error in
print("請求失斔契狻隅熙!錯(cuò)誤原因:", error)
}).disposed(by: disposeBag)
2稽煤,使用 requestData 請求數(shù)據(jù)
(1)下面代碼同樣是獲取豆瓣頻道數(shù)據(jù),并將返回結(jié)果輸出到控制臺(tái)中囚戚。
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
requestData(.get, url).subscribe(onNext: {
response, data in
//數(shù)據(jù)處理
let str = String(data: data, encoding: String.Encoding.utf8)
print("返回的數(shù)據(jù)是:", str ?? "")
}).disposed(by: disposeBag)
(2)使用 requestData
的話酵熙,不管請求成功與否都會(huì)進(jìn)入到 onNext
這個(gè)回調(diào)中。如果我們想要根據(jù)響應(yīng)狀態(tài)進(jìn)行一些相應(yīng)操作驰坊,通過 response
參數(shù)即可實(shí)現(xiàn)匾二。
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/jxxxxxxx/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
requestData(.get, url).subscribe(onNext: {
response, data in
//判斷響應(yīng)結(jié)果狀態(tài)碼
if 200 ..< 300 ~= response.statusCode {
let str = String(data: data, encoding: String.Encoding.utf8)
print("請求成功!返回的數(shù)據(jù)是:", str ?? "")
}else{
print("請求失斎健察藐!")
}
}).disposed(by: disposeBag)
3,獲取 String 類型數(shù)據(jù)
(1)如果請求的數(shù)據(jù)是字符串類型的舟扎,我們可以在 request
請求時(shí)直接通過 responseString()
方法實(shí)現(xiàn)自動(dòng)轉(zhuǎn)換分飞,省的在回調(diào)中還要手動(dòng)將 data
轉(zhuǎn)為 string
。
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
request(.get, url)
.responseString()
.subscribe(onNext: {
response, data in
//數(shù)據(jù)處理
print("返回的數(shù)據(jù)是:", data)
}).disposed(by: disposeBag)
(2)當(dāng)然更簡單的方法就是直接使用 requestString
去獲取數(shù)據(jù)睹限。
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)!
//創(chuàng)建并發(fā)起請求
requestString(.get, url)
.subscribe(onNext: {
response, data in
//數(shù)據(jù)處理
print("返回的數(shù)據(jù)是:", data)
}).disposed(by: disposeBag)
三譬猫、手動(dòng)發(fā)起請求、取消請求
? ? ? ? 在很多情況下邦泄,網(wǎng)絡(luò)請求并不是由程序自動(dòng)發(fā)起的删窒。可能需要我們點(diǎn)擊個(gè)按鈕顺囊,或者切換個(gè)標(biāo)簽時(shí)才去請求數(shù)據(jù)肌索。而且除了可以手動(dòng)發(fā)起請求外,同樣可能還需要能手動(dòng)取消上一次的網(wǎng)絡(luò)請求(如果未完成)特碳。下面通過樣例演示這個(gè)功能如何實(shí)現(xiàn)诚亚。
1,效果圖
(1)每次點(diǎn)擊“發(fā)起請求”按鈕則去請求一次數(shù)據(jù)午乓。
(2)如果請求沒返回時(shí)站宗,點(diǎn)擊“取消請求”則可將其取消(取消后即使返回?cái)?shù)據(jù)也不處理了)。
2益愈,樣例代碼
import UIKit
import RxSwift
import RxCocoa
import Alamofire
class ViewController: UIViewController {
//“發(fā)起請求”按鈕
@IBOutlet weak var startBtn: UIButton!
//“取消請求”按鈕
@IBOutlet weak var cancelBtn: UIButton!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建URL對(duì)象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)!
//發(fā)起請求按鈕點(diǎn)擊
startBtn.rx.tap.asObservable()
.flatMap {
request(.get, url).responseString()
.takeUntil(self.cancelBtn.rx.tap) //如果“取消按鈕”點(diǎn)擊則停止請求
}
.subscribe(onNext: {
response, data in
print("請求成功梢灭!返回的數(shù)據(jù)是:", data)
}, onError: { error in
print("請求失敗蒸其!錯(cuò)誤原因:", error)
}).disposed(by: disposeBag)
}
}