???? Moya
是一個基于 Alamofire
的更高層網(wǎng)絡請求封裝抽象層唆迁。它可以對我們項目中的所有請求進行集中管理,方便開發(fā)與維護。同時 Moya
自身也提供了對 RxSwift
的擴展,通過與 RxSwift
的結(jié)合影钉,能讓 Moya
變得更加強大。下面我就通過樣例演示如何使用“RxSwift + Moya
”這個組合進行開發(fā)掘剪。
一 平委、安裝配置
? ? ? ? 航哥之前也寫過關(guān)于 Moya
的文章(點擊查看),當時是通過 CocoaPods
來進行安裝配置夺谁。這次改用手動配置作為演示廉赔。
(1)首先將需要用到的庫下載到本地:
- RxSwift:https://github.com/ReactiveX/RxSwift
- Alamofire:https://github.com/Alamofire/Alamofire
- Moya:https://github.com/Moya/Moya
- Result:https://github.com/antitypical/Result
(2)接著在項目中引入并配置即可。
二匾鸥、數(shù)據(jù)請求樣例
1蜡塌,效果圖
? ? ? ? 我們使用 Moya
調(diào)用豆瓣 FM
的 API
接口,獲取所有的頻道列表并輸出到控制臺中勿负。
2馏艾,網(wǎng)絡請求層
? ? ? ? 我們先創(chuàng)建一個 DouBanAPI.swift
文件作為網(wǎng)絡請求層,里面的內(nèi)容如下:
- 首先定義一個
provider
,即請求發(fā)起對象琅摩。往后我們?nèi)绻l(fā)起網(wǎng)絡請求就使用這個provider
铁孵。 - 接著聲明一個
enum
來對請求進行明確分類,這里我們定義兩個枚舉值分別表示獲取頻道列表房资、獲取歌曲信息蜕劝。 - 最后讓這個
enum
實現(xiàn)TargetType
協(xié)議,在這里面定義我們各個請求的url
轰异、參數(shù)岖沛、header
等信息。
import Foundation
import Moya
import RxMoya
//初始化豆瓣FM請求的provider
let DouBanProvider = MoyaProvider<DouBanAPI>()
/** 下面定義豆瓣FM請求的endpoints(供provider使用)**/
//請求分類
public enum DouBanAPI {
case channels //獲取頻道列表
case playlist(String) //獲取歌曲
}
//請求配置
extension DouBanAPI: TargetType {
//服務器地址
public var baseURL: URL {
switch self {
case .channels:
return URL(string: "https://www.douban.com")!
case .playlist(_):
return URL(string: "https://douban.fm")!
}
}
//各個請求的具體路徑
public var path: String {
switch self {
case .channels:
return "/j/app/radio/channels"
case .playlist(_):
return "/j/mine/playlist"
}
}
//請求類型
public var method: Moya.Method {
return .get
}
//請求任務事件(這里附帶上參數(shù))
public var task: Task {
switch self {
case .playlist(let channel):
var params: [String: Any] = [:]
params["channel"] = channel
params["type"] = "n"
params["from"] = "mainsite"
return .requestParameters(parameters: params,
encoding: URLEncoding.default)
default:
return .requestPlain
}
}
//是否執(zhí)行Alamofire驗證
public var validate: Bool {
return false
}
//這個就是做單元測試模擬的數(shù)據(jù)搭独,只會在單元測試文件中有作用
public var sampleData: Data {
return "{}".data(using: String.Encoding.utf8)!
}
//請求頭
public var headers: [String: String]? {
return nil
}
}
3婴削,使用樣例
(1)我們在視圖控制器中通過上面的定義的 provider
即可發(fā)起請求,獲取數(shù)據(jù)戳稽。具體代碼如下:
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//獲取數(shù)據(jù)
DouBanProvider.rx.request(.channels)
.subscribe { event in
switch event {
case let .success(response):
//數(shù)據(jù)處理
let str = String(data: response.data, encoding: String.Encoding.utf8)
print("返回的數(shù)據(jù)是:", str ?? "")
case let .error(error):
print("數(shù)據(jù)請求失敗!錯誤原因:", error)
}
}.disposed(by: disposeBag)
}
}
(2)訂閱相關(guān)的代碼還可以換種方式寫:
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//獲取數(shù)據(jù)
DouBanProvider.rx.request(.channels)
.subscribe(onSuccess: { response in
//數(shù)據(jù)處理
let str = String(data: response.data, encoding: String.Encoding.utf8)
print("返回的數(shù)據(jù)是:", str ?? "")
},onError: { error in
print("數(shù)據(jù)請求失敗!錯誤原因:", error)
}).disposed(by: disposeBag)
}
}