Swift 網絡請求庫Moya的使用

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

func loadData(){
        var param = [String:String]()
        param["pageNo"] = "1"
        param["Type"] = "8"
        param["pageSize"] = "10"

        Alamofire.request("https://www.baidu.com",parameters:param).responseJSON { (responseJson) in
            switch responseJson.result {
            case .success(let data):
                print(data)
                //Alamofire默認返回的是一個解析過的數據結構,這裏代表一個字典
                if data is Dictionary<String, Any>{
                    let data2 = data as! Dictionary<String, Any>
                    print(data2["Msg"]!)
                }
            case .failure(let error):
                print(error)
            }
        }
    }

Moya的優缺點:

(1)在我們項目的 Service、View、或者 Model 文件中可能都會出現請求網絡數據的情況,如果直接使用 Alamofire,不僅很繁瑣,而且還會使代碼變得很混亂。
(2)過去我們通常的做法是在項目中添加一個網絡請求層(比如叫做 APIManager、或者 NetworkModel),用來管理網絡請求。但這樣做可能會遇到一些問題:
難以開發一個新的 App(不知從哪裏下手)
難以維護現有的 App(這一層比較混亂,混合了各種請求不好管理。)
難以做做單元測試。
(3)而 Moya 作爲一個基於 Alamofire 的更高層網絡請求封裝抽象層,擁有更好更清晰的網絡管理。不僅可以輕鬆實現簡單的事情,對於複雜的情況也輕鬆應對。它有如下優點:
定義了一個清晰的網絡結構(通過枚舉值定義不同的請求)
可以簡單地進行網絡單元測試

Moya的使用方法

1、首先創建一個swift文件,創建一個枚舉,定義三個請求,如下:

/*
 封裝的moya請求管理類
 */
enum HttpRequest {
    case shujuList(channnel:String , pn:Int , ps:Int) //列表數據請求,帶有相關值的枚舉,
    case othetRequest(str:String) //帶一個參數的請求
    case otherRequest2 //不帶參數的請求
}

枚舉中包含三個請求,分別是請求列表數據(附帶三個參數)和一個其他的附帶一個參數的請求和一個不帶參數的請求。

2、創建擴展,遵循協議實現協議的方法,如下:

/*
 遵循mayo協議,實現方法
 */
extension HttpRequest : TargetType{

    //服務器地址
    var baseURL: URL {
        return URL(string:"www.baidu.com")!
    }

    //各個請求的具體路徑
    var path: String {
        switch self {
        case .shujuList:
            return "ArticleList"
        case .othetRequest:
            return "someOtherPath"
        default:
            return ""
        }
    }

    //請求方式
    var method: Moya.Method {
        return .get
    }

     //請求任務事件(這裏附帶上參數)
    var task: Task {
        var param:[String:Any] = [:]

        switch self {
        case let .shujuList(channel , pn , ps):
            param["Type"] = channel
            param["pageNo"] = pn
            param["pageSize"] = ps
        case let .othetRequest(str):
            param["str"] = str
        default:
            //不需要傳參數的走這裏
            return .requestPlain
        }
        return .requestParameters(parameters: param, encoding: URLEncoding.default)

    }

    //是否執行Alamofire驗證
    public var validate: Bool {
        return false
    }

    //這個就是做單元測試模擬的數據,只會在單元測試文件中有作用
    public var sampleData: Data {
        return "{}".data(using: String.Encoding.utf8)!
    }

    //設置請求頭
    public var headers: [String: String]? {
        return nil
    }
}

這裏通過TargetType協議的方法,設置了baseURL,請求方式和和參數,以及請求頭等各個請求的參數。

3、發起網絡請求

在需要的地方,調用網絡管理類發起三個請求中的一個,這裏以第一個爲例,代碼如下:

func loadDataWithMoya(pn:Int , ps:Int) -> () {
    let provide = MoyaProvider<HttpRequest>()
    provide.request(.shujuList(channnel: "8", pn: pn, ps: ps)) { Result in
        switch Result {
        case let .success(response):
            //數據解析
            let json = JSON(response.data)
            print(json)

        case let .failure(error):
            print(error)
        }
    }
}

需要注意的是,Moya默認回傳的是二進制的裸數據,需要自己進行解析,我使用了SwiftyJSON進行了解析。如果要進行模型轉換的話推薦系統自帶的Codable。

Moya參考博客
SwiftyJSON參考博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章