Moya是Swift中的網絡庫Alamofire的二次封裝,Alamofire本身使用起來是很簡單方便的,例子如下:

Moya的優(yōu)缺點:
(1)在我們項目的 Service、View、或者 Model 文件中可能都會出現(xiàn)請求網絡數據的情況,如果直接使用 Alamofire,不僅很繁瑣,而且還會使代碼變得很混亂。
(2)過去我們通常的做法是在項目中添加一個網絡請求層(比如叫做 APIManager,用來管理網絡請求。但這樣做可能會遇到一些問題:
多人開發(fā)的時候很難降低耦合度
難以維護現(xiàn)有的 App(這一層比較混亂,混合了各種請求不好管理。)
難以做做單元測試。
(3)而 Moya 作為一個基于 Alamofire 的更高層網絡請求封裝抽象層,擁有更好更清晰的網絡管理。不僅可以輕松實現(xiàn)簡單的事情,而且是一個允許高度自定義的網絡層,可以根據具體的需求進行接口的設置。它有如下優(yōu)點:
定義了一個清晰的網絡結構(通過枚舉值定義不同的請求)
多人開發(fā)的時候降低耦合度
可以簡單地進行網絡單元測試
結構圖如下:

那么Moya如何使用呢?
1、首先創(chuàng)建一個swift文件,創(chuàng)建一個枚舉,定義三個請求,如下:
/*
?封裝的moya請求管理類
?*/
enum HttpRequest {
? ? case showHome(channnel:String , pn:Int)//列表數據請求,帶有相關值的枚舉,
? ? case indexHome//不帶參數的請求
}
枚舉中包含兩個請求,分別是請求列表數據(附帶參數)和一個不帶參數的請求。
2、創(chuàng)建擴展,遵循協(xié)議實現(xiàn)協(xié)議的方法,如下:
/*
?遵循mayo協(xié)議,實現(xiàn)方法
?*/
extension HttpRequest : TargetType{
? ?//服務器地址
? ? var baseURL:URL{
? ? ? ? return URL(string:"http://www.inquireb2b.com/api/")!
? ? }
? ? //各個請求的具體路徑
? ? var path:String{
? ? ? ? switch self{
? ? ? ? case .showHome(let channnel,let?pn)?:?
????????????return "introduction.php?page=\(pn)"
? ? ? ? case .indexHome?:return"/index.php"
? ? ? ? }
? ? }
//請求參數
?var parameters: [String:Any]? {
? ? ? ? switch self {
? ? ? ? case .showHome(let?channnel,let?pn):
? ? ? ? ? ? return?["channnel": channnel,"page":pn]
? ? ? ? case .indexHome:
? ? ? ? ? ? return nil
? ? ? ? }
? ? }
? ? //請求方式
? ? var method:Moya.Method{
? ? ? ? return .post
? ? }
// 請求頭
? ? public var headers: [String:String]? {
//? ? ? ? return ["Content-Type" : "application/x-www-form-urlencoded; charset=utf-8"]
? ? ? ? return nil
? ? }
// 這個就是做單元測試模擬的數據,只會在單元測試文件中有作用
? ? public var sampleData:Data{
? ? ? ? return "{}".data(using:String.Encoding.utf8)!
? ? }
? ? //請求任務事件(這里附帶上參數)
? ? var task:Task{
????? ? switch self{
? ? ? ????? case?.showHome(_,_):
? ? ? ? ????? ? return .requestParameters(parameters:parameters!, encoding:URLEncoding.default)
? ? ? ? ????default:
????????????????//不需要傳參數的走這里
????? ? ? ? ? ? return ?.requestPlain
? ? ? ? ????}
? ? }
}
這里通過TargetType協(xié)議的方法,設置了baseURL,請求方式和和參數,以及請求頭等各個請求的參數。
3、發(fā)起網絡請求
在需要的地方,調用網絡管理類發(fā)起三個請求中的一個,這里以第一個為例,代碼如下:
?func loadDataWithMoya(channnel:String, pn:Int) -> () {
? ? ? ? let provide = MoyaProvider()
? ? ? ? provide.request(.shujuList(channnel:channnel, pn: pn)) { Resultin
? ? ? ? ? ? switch Result {
? ? ? ? ? ? case let.success(response):
? ? ? ? ? ? ? ? //數據解析
? ? ? ? ? ? ? ? let json = JSON(response.data)
? ? ? ? ? ? ? ? print(json)
? ? ? ? ? ? case let.failure(error):
? ? ? ? ? ? ? ? print(error)
? ? ? ? ? ? }
? ? ? ? }
? ? }
需要注意的是,Moya默認回傳的是二進制的裸數據,需要自己進行解析,我使用了SwiftyJSON進行了解析。如果要進行模型轉換的話推薦系統(tǒng)自帶的Codable。