? ? ? ?RxSwift
(或者說 RxCocoa
)除了對系統原生的 UI
控件提供了 rx
擴展外,對 URLSession
也進行了擴展,從而讓我們可以很方便地發送 HTTP
請求。
一、請求網絡數據
1,通過 rx.response 請求數據
(1)下面代碼我們通過豆瓣提供的音樂頻道列表接口獲取數據,并將返回結果輸出到控制臺中。
//創建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)
(2)從上面樣例可以發現,不管請求成功與否都會進入到 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)
2,通過 rx.data 請求數據
rx.data
與rx.response
的區別:
- 如果不需要獲取底層的
response
,只需知道請求是否成功,以及成功時返回的結果,那么建議使用rx.data
。- 因為
rx.data
會自動對響應狀態碼進行判斷,只有成功的響應(狀態碼為 200~300)才會進入到onNext
這個回調,否則進入onError
這個回調。
(1)如果不需要考慮請求失敗的情況,只對成功返回的結果做處理可以在 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)
(2)如果還要處理失敗的情況,可以在 onError
回調中操作。
//創建URL對象
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 in
let str = String(data: data, encoding: String.Encoding.utf8)
print("請求成功!返回的數據是:", str ?? "")
}, onError: { error in
print("請求失敗!錯誤原因:", error)
}).disposed(by: disposeBag)
二、手動發起請求、取消請求
? ? ? ? 在很多情況下,網絡請求并不是由程序自動發起的。可能需要我們點擊個按鈕,或者切換個標簽時才去請求數據。除了手動發起請求外,同樣的可能還需要手動取消上一次的網絡請求(如果未完成)。下面通過樣例演示這個如何實現。
1,效果圖
(1)每次點擊“發起請求”按鈕則去請求一次數據。
(2)如果請求沒返回時,點擊“取消請求”則可將其取消(取消后即使返回數據也不處理了)。
2,樣例代碼
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
//“發起請求”按鈕
@IBOutlet weak var startBtn: UIButton!
//“取消請求”按鈕
@IBOutlet weak var cancelBtn: UIButton!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創建URL對象
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 in
let str = String(data: data, encoding: String.Encoding.utf8)
print("請求成功!返回的數據是:", str ?? "")
}, onError: { error in
print("請求失敗!錯誤原因:", error)
}).disposed(by: disposeBag)
}
}