• MoyaSwift中的网络库Alamofire的二次封装,Alamofire本身使用起来是很简单方便的,例子如下: func loadData(){ var param = [String:String]() param["pageNo"] = "1" param["...

    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参考博客

    展开全文
  • Moya使用demoMoya面向协议Moya的模块组成代码demo Moya Moya是一个网络抽象层,它在底层将Alamofire进行封装,对外提供更简洁的接口供开发者调用。在Objective-C中,大部分开发者会使用AFNetwork进行网络请求,当...

    Moya

    Moya是一个网络抽象层,它在底层将Alamofire进行封装,对外提供更简洁的接口供开发者调用。在Objective-C中,大部分开发者会使用AFNetwork进行网络请求,当业务复杂一些时,会对AFNetwork进行二次封装,编写一个适用于自己项目的网络抽象层。在Objective-C中,有著名的YTKNetwork,它将AFNetworking封装成抽象父类,然后根据每一种不同的网络请求,都编写不同的子类,子类继承父类,来实现请求业务。Moya在项目层次中的地位,有点类似于YTKNetwork。可以看下图对比
    网络请求层级
    如果单纯把Moya等同于swift版的YTKNetwork,那就是比较错误的想法了。Moya的设计思路和YTKNetwork差距非常大。上面我在介绍YTKNetwork时在强调子类和父类,继承,是因为YTKNetwork是比较经典的利用OOP思想(面向对象)设计的产物。基于swiftMoya虽然也有使用到继承,但是它的整体上是以POP思想(Protocol Oriented Programming,面向协议编程)为主导的。

    面向协议

    请看我的其中一篇文章有介绍到

    Moya的模块组成

    Moya层级

    1. Provider:provider是一个提供网络请求服务的提供者。通过一些初始化配置之后,在外部可以直接用provider来发起request。
    2. Request:在使用Moya进行网络请求时,第一步需要进行配置,来生成一个Request。首先按照官方文档,创建一个枚举,遵守TargetType协议,并实现协议所规定的属性。为什么要创建枚举来遵守协议,枚举结合switch语句,使得API管理起来比较方便。
    3. 根据创建了一个遵守TargetType协议的名为Myservice的枚举,我们完成了如下几个变量的设置。
    	baseURL
    	path
    	method
    	sampleData
    	task
    	headers
    

    代码demo

    //
    //  YShareApI.swift
    //  
    //
    //  Created by bruce yao on 2019/4/10.
    //  Copyright © 2019 bruce yao. All rights reserved.
    //
    
    import UIKit
    import Moya
    import RxCocoa
    import Result
    import SwiftyJSON
    
    //初始rovider
    let YShareApiProvider = MoyaProvider<YShareAPI>(plugins: [RequestLoadingPlugin()])
    
    /** 请求的endpoints)**/
    //请求分类
    enum YShareAPI {
        case shareNavList:
        case shareList(pageSize: Int, pageNum: Int):
    }
    //请求配置
    extension YShareAPI: TargetType {
        //服务器地址
        public var baseURL: URL {
            switch self {
            default:
                return URL(string: HD_Search_Base)!
            }
        }
        
        //各个请求的具体路径
        public var path: String {
            switch self {
            case .shareNavList:
                return "manage/navigation/getNavigationList"
            default:
                return "ddddd/list"
            }
        }
        
        //请求类型
        public var method: Moya.Method {
            switch self {
           
            default:
                return .get
            }
        }
        
        //请求任务事件(这里附带上参数)
        public var task: Task {
            switch self {
            case .shareNavList:
                return .requestPlain
           case .shareList(let pageSize, let pageNum):
                var params: [String: Any] = [:]
                params["pageSize"] = pageSize
                params["pageNum"] = pageNum
                return .requestParameters(parameters: params, 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]? {
            switch self {
            default:
                return ["Content-type": "application/json"]
            }
        }
    }
    
    //
    //  RequestLoadingPlugin.swift
    //  
    //
    //  Created by bruce yao on 2019/1/25.
    //  Copyright . All rights reserved.
    //
    
    import UIKit
    import Foundation
    import MBProgressHUD
    import Moya
    import Result
    
    class RequestLoadingPlugin: PluginType {
        
        func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
            print("prepare")
            var mRequest = request
            mRequest.timeoutInterval = 20
            return mRequest
        }
        func willSend(_ request: RequestType, target: TargetType) {
            print("开始请求")
            if SwiftIsShowHud == true {
                let keyViewController = UIApplication.shared.keyWindow?.rootViewController
                if (keyViewController != nil) {
                    MBProgressHUD.showAdded(to: keyViewController!.view, animated: true)
                }
            }
            
        }
        
        func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
            print("结束请求")
            let keyViewController = UIApplication.shared.keyWindow?.rootViewController
            if (keyViewController != nil) {
                MBProgressHUD.hide(for: keyViewController!.view, animated: true)
                //            MBProgressHUD.
            }
            
            
           guard case Result.failure(_) = result
            else {
                let respons = result.value
                let dic: Dictionary<String, Any>? =
                    try? JSONSerialization.jsonObject(with: respons!.data, options: .mutableContainers) as! Dictionary<String, Any>
                
                if dic != nil {
                    if dic?.keys.contains("status") == true {
                        if dic?["status"] as! Int == 11 || dic?["status"] as! Int == 12 {
                            print("Token 失效")
                        }
                    }
                    
                    if dic?.keys.contains("code") == true {
                        if dic?["code"] as! Int == 11 || dic?["code"] as! Int == 12 {
                            print("Token 失效")
                        }
                    }
                }
                return
            }
            let errorReason: String = (result.error?.errorDescription)!
            print("请求失败:\(errorReason)")
            var tip = ""
            if errorReason.contains("The Internet connection appears to be offline") {
                tip = "网络不给力,请检查您的网络"
            }else if errorReason.contains("Could not connect to the server") {
                tip = "无法连接服务器"
            }else {
               tip = "请求失败"
            }
            /// 使用tip文字 进行提示
        }
    }
    

    Controller中使用

    代码片段

    import RxSwift
    import RxCocoa
    import ObjectMapper
    
    YShareApiProvider
                    .rx.request(input.category)
                    .mapObject(YBaseModel<T>.self)
                    .subscribe(onSuccess: { (baseModel) in
                        print("请求成功 返回数据如下")
                        if baseModel.status != 0 {
                            
                            return
                        }
                        
                    }, onError: {error in
                        print("Error:请求错误")
                       
                    }).disposed(by: self.disposeBag)
                }, onError: { (error) in
                    
            }, onCompleted: {
                
            }) {
                
                }.disposed(by: disposeBag)
    
    展开全文
  • Moya基于Alamofire进行封装,使用更加简单,维护更加方便。 GitHub地址:https://github.com/Moya/Moya.git 1.使用CocoaPods导入Moya: pod 'Moya', '~&amp;gt; 11.0.2' 2.创建一个对象实现TargetType协议...

    GitHub地址:https://github.com/Moya/Moya.git
    Moya基于Alamofire进行封装,使用更加简单,维护更加方便。
    1.使用CocoaPods导入Moya:

    pod 'Moya', '~> 11.0.2'
    

    2.创建一个对象实现TargetType协议的方法

    import Foundation
    import Moya
    
    enum ScanServer {
        case qrLogin(appname: String, nonce: String, address: String)
        case qrLoginConfirm(appname: String, nonce: String, address: String, confirm: String)
    }
    
    extension ScanServer: TargetType {
        
        var headers: [String : String]? {
            return ["Content-type" : "application/json"]
        }
        
        var baseURL: URL {
            return URL(string: GlobalConfig.current.scanServerBase)!
        }
        
        var path: String {
            switch self {
            case .qrLogin(_):
                return "/qrlogin"
            case .qrLoginConfirm(_):
                return "/qrconfirm"
            }
        }
        
        var method: Moya.Method {
            switch self {
            case .qrLogin(_):
                return .get
            default:
                return .post
            }
        }
        
        var parameters: [String: Any]? {
            var paramsDict: [String : Any] = [:]
            switch self {
            case .qrLogin(let appname, let nonce, let address):
                paramsDict["appname"] = appname
                paramsDict["nonce"] = nonce
                paramsDict["address"] = address
            case .qrLoginConfirm(let appname, let nonce, let address, let confirm):
                paramsDict["appname"] = appname
                paramsDict["nonce"] = nonce
                paramsDict["address"] = address
                paramsDict["confirm"] = confirm
            }
            return paramsDict
        }
        
        var parameterEncoding: ParameterEncoding {
            return URLEncoding.default
        }
        
        var sampleData: Data {
            return "".data(using: .utf8)!
        }
        
        var task: Task {
            switch self {
            case .qrLogin(_):
                return .requestParameters(parameters: parameters ?? [:], encoding: URLEncoding.default)//get方式参数拼接成url
            default:
                return .requestParameters(parameters: parameters ?? [:], encoding: JSONEncoding.default)//post方式参数是json格式
            }
        }
        
    }
    
    

    3.创建一个对象实现MoyaProviderType协议的方法

    import Moya
    import Result
    import SwiftyJSON
    
    enum ProviderError: LocalizedError {
        case server
        case data
        case message(msg: String)
        
        var description: String {
            switch self {
            case .server:
                return "Failed to connect to server".localized
            case .data:
                return "Failed to get data".localized
            case .message(let msg):
                return msg
            }
        }
    }
    
    let networkPlugin = NetworkActivityPlugin { (change, _) in
        switch(change){
        case .ended:
            DispatchQueue.main.async {
                UIApplication.shared.isNetworkActivityIndicatorVisible = false
            }
        case .began:
            DispatchQueue.main.async {
                UIApplication.shared.isNetworkActivityIndicatorVisible = true
            }
        }
    }
    
    let scanClosure = { (endpoint: Endpoint, done: @escaping MoyaProvider<ScanServer>.RequestResultClosure) in
        do {
            var request: URLRequest = try endpoint.urlRequest()
            request.timeoutInterval = 30
            done(.success(request))
        } catch  {
            print("\(error)")
        }
    }
    
    class ScanProvider {
        
        static let shared = ScanProvider()
        
        let provider = MoyaProvider<ScanServer>(requestClosure: scanClosure, plugins: [networkPlugin])
        
        private func failureAction(error: ProviderError) {
            if NetworkingManager.status == .none || NetworkingManager.status == .unknown {
                Toast.showMessage(message: NetworkingManager.status.description)
            } else {
                Toast.showMessage(message: error.description)
            }
        }
        
        func qrLogin(appname: String,
                     nonce: String,
                     address: String,
                     completion: @escaping (Result<Bool, ProviderError>) -> Void) {
            provider.request(.qrLogin(
                appname: appname,
                nonce: nonce,
                address: address)) { result in
                    switch result {
                    case .success(let responseData):
                        if let response = JSONResponseFormatter(responseData.data) {
                            print(response)
                            if let status = response["state"] as? Int {
                                completion(.success(status == 1 ? true : false))
                            }
                        }
                    case .failure(_):
                        self.failureAction(error: .server)
                        completion(.failure(.server))
                    }
            }
        }
        
        func qrLoginConfirm(appname: String,
                            nonce: String,
                            address: String,
                            confirm: String,
                            completion: @escaping (Result<Bool, ProviderError>) -> Void) {
            provider.request(.qrLoginConfirm(
                appname: appname,
                nonce: nonce,
                address: address,
                confirm: confirm)) { result in
                    switch result {
                    case .success(let responseData):
                        if let response = JSONResponseFormatter(responseData.data) {
                            print(response)
                            if let status = response["state"] as? Int {
                                completion(.success(status == 1 ? true : false))
                            }
                        }
                    case .failure(_):
                        self.failureAction(error: .server)
                        completion(.failure(.server))
                    }
            }
        }
    }
    

    4.发起请求

    ScanProvider.shared.qrLogin(
        appname: result.qrStringAppName,
        nonce: result.qrStringNonce,
        address: result.address
    ) {[weak self] (res) in
        guard let `self` = self else { return }
        switch res {
        case .success(_):
            print("success")
        case .failure(_):
            print("failure")
        }
    }
    
    展开全文
  • Moya是一个网络抽象层,它在底层将Alamofire进行封装,对外提供更简洁的接口供开发者调用。在Objective-C中,大部分开发者会使用AFNetwork进行网络请求,当业务复杂一些时,会对AFNetwork进行二次封装,编写一个适用...

    一、简介

    github地址

    Moya是一个网络抽象层,它在底层将Alamofire进行封装,对外提供更简洁的接口供开发者调用。在Objective-C中,大部分开发者会使用AFNetwork进行网络请求,当业务复杂一些时,会对AFNetwork进行二次封装,编写一个适用于自己项目的网络抽象层。在Objective-C中,有著名的YTKNetwork,它将AFNetworking封装成抽象父类,然后根据每一种不同的网络请求,都编写不同的子类,子类继承父类,来实现请求业务。Moya在项目层次中的地位,有点类似于YTKNetwork。可以看下图对比
    在这里插入图片描述

    二、模块组成

    在这里插入图片描述

    • Provider:provider是一个提供网络请求服务的提供者。通过一些初始化配置之后,在外部可以直接用provider来发起request。
    • Request:在使用Moya进行网络请求时,第一步需要进行配置,来生成一个Request。首先按照官方文档,创建一个枚举,遵守TargetType协议,并实现协议所规定的属性。为什么要创建枚举来遵守协议,枚举结合switch语句,使得API管理起来比较方便。
      根据创建了一个遵守TargetType协议的名为YShareAPI的枚举,我们完成了如下几个变量的设置。
    1. baseURL
    2. path
    3. method
    4. sampleData
    5. task
    6. headers

    三、简单使用Demo

    引入框架

    pod 'Moya', '~> 14.0'
    
    # or 
    
    pod 'Moya/RxSwift', '~> 14.0'
    
    # or
    
    pod 'Moya/ReactiveSwift', '~> 14.0'
    

    YShareApI.swift

    //
    //  YShareApI.swift
    //  
    //
    //  Created by bruce yao on 2019/4/10.
    //  Copyright © 2019 bruce yao. All rights reserved.
    //
    
    import UIKit
    import Moya
    import RxCocoa
    import Result
    import SwiftyJSON
    
    //初始rovider
    let YShareApiProvider = MoyaProvider<YShareAPI>()
    
    /** 请求的endpoints)**/
    //请求分类
    enum YShareAPI {
        case shareNavList:
        case shareList(pageSize: Int, pageNum: Int):
    }
    //请求配置
    extension YShareAPI: TargetType {
        //服务器地址
        public var baseURL: URL {
            switch self {
            default:
                return URL(string: HD_Search_Base)!
            }
        }
        
        //各个请求的具体路径
        public var path: String {
            switch self {
            case .shareNavList:
                return "manage/navigation/getNavigationList"
            default:
                return "ddddd/list"
            }
        }
        
        //请求类型
        public var method: Moya.Method {
            switch self {
           
            default:
                return .get
            }
        }
        
        //请求任务事件(这里附带上参数)
        public var task: Task {
            switch self {
            case .shareNavList:
                return .requestPlain
           case .shareList(let pageSize, let pageNum):
                var params: [String: Any] = [:]
                params["pageSize"] = pageSize
                params["pageNum"] = pageNum
                return .requestParameters(parameters: params, 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]? {
            switch self {
            default:
                return ["Content-type": "application/json"]
            }
        }
    }
    
    

    Controller中使用

     YShareApiProvider.request(input.category) { result in
                switch self {
                    case let .success(response):
                       let json = try response.mapJSON()
                        print("\(json)");
                        
                    case let .failure(error):
                        break;
                    }
            }
    
    

    Moya.Response里面有一些常用的方法:

    // 转换为Image
    func mapImage() throws -> Image;
    
    // 转换为Json
    func mapJSON(failsOnEmptyData: Bool = true) throws -> Any;
    
    // 装换为String
    func mapString(atKeyPath keyPath: String? = nil) throws -> String;
    
    // 转换为对应的model
    func map<D: Decodable>(_ type: D.Type, atKeyPath keyPath: String? = nil, using decoder: JSONDecoder = JSONDecoder(), failsOnEmptyData: Bool = true) throws -> D;
    

    四、Moya的高级用法

    Moya实现了网络层的高度抽象,它是通过以下管道来实现这一点的:
    在这里插入图片描述

    Provider 将 Targets 映射成 Endpoints, 然后再将 Endpoints 映射成真正的 Request。

    我们可以看一下Provider的构造方法:

    /// Initializes a provider.
        public init(endpointClosure: @escaping EndpointClosure = MoyaProvider.defaultEndpointMapping,
                    requestClosure: @escaping RequestClosure = MoyaProvider.defaultRequestMapping,
                    stubClosure: @escaping StubClosure = MoyaProvider.neverStub,
                    callbackQueue: DispatchQueue? = nil,
                    manager: Manager = MoyaProvider<Target>.defaultAlamofireManager(),
                    plugins: [PluginType] = [],
                    trackInflights: Bool = false) {
    
            self.endpointClosure = endpointClosure
            self.requestClosure = requestClosure
            self.stubClosure = stubClosure
            self.manager = manager
            self.plugins = plugins
            self.trackInflights = trackInflights
            self.callbackQueue = callbackQueue
        }
    

    Provider输入的参数包括:EndpointClosure,RequestClosure,StubClosure, callbackQueue,plugins, trackInflights

    1.EndpointClosure

    EndpointClosure = (Target) -> Endpoint就是定义如何将 Targets 映射为Endpoints

    在这个闭包中,你可以改变taskmethodurlheaders 或者 sampleResponse。比如,我们可能希望将应用程序名称设置到HTTP头字段中,从而用于服务器端分析。

    let endpointClosure = { (target: MyTarget) -> Endpoint in
        let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)
        return defaultEndpoint.adding(newHTTPHeaderFields: ["APP_NAME": "MY_AWESOME_APP"])
    }
    let provider = MoyaProvider<GitHub>(endpointClosure: endpointClosure)
    

    2.requestClosure

    RequestClosure = (Endpoint, @escaping RequestResultClosure) -> Void 就是 Endpoint 转换为 Request的一个拦截,它还可以修改请求的结果( 通过调用RequestResultClosure = (Result<URLRequest, MoyaError>) )

    let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in
        do {
            var request = try endpoint.urlRequest()
            // Modify the request however you like.
            done(.success(request))
        } catch {
            done(.failure(MoyaError.underlying(error)))
        }
    
    }
    let provider = MoyaProvider<GitHub>(requestClosure: requestClosure)
    

    3.stubClosure

    这个闭包返回 .never (默认的), .immediate 或者可以把stub请求延迟指定时间的.delayed(seconds)三个中的一个。 例如, .delayed(0.2) 可以把每个stub 请求延迟0.2s. 这个在单元测试中来模拟网络请求是非常有用的。

    4.manager

    Provider里面你可以自定义一个 Alamofire.Manager实例对象。

    // 这是Moya默认的manager
    public final class func defaultAlamofireManager() -> Manager {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
    
        let manager = Alamofire.Manager(configuration: configuration)
        manager.startRequestsImmediately = false //设定false,为了单元测试
        return manager
    }
    

    5.plugins

    最后, 您可能也提供一个plugins数组给provider。 这些插件会在请求被发送前及响应收到后被执行。 Moya已经提供了一些插件: 一个是 网络活动(NetworkActivityPlugin),一个是记录所有的 网络活动 (NetworkLoggerPlugin), 还有一个是 HTTP Authentication。

    plugins里面的对象都遵循协议PluginType, 协议了规定了几种方法,阐述了什么时候会被调用。

    public protocol PluginType {
        /// modified Request 请求发送之前调用(主要用于修改request)
        /// Called to modify a request before sending.
        func prepare(_ request: URLRequest, target: TargetType) -> URLRequest
    
        /// Request 请求发送之前调用
        /// Called immediately before a request is sent over the network (or stubbed).
        func willSend(_ request: RequestType, target: TargetType)
    
        /// 接收到了response,completion handler 之前调用
        /// Called after a response has been received, but before the MoyaProvider has invoked its completion handler.
        func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType)
    
        /// completion handler 之前调用(主要用于修改result)
        /// Called to modify a result before completion.
        func process(_ result: Result<Moya.Response, MoyaError>, target: TargetType) -> Result<Moya.Response, MoyaError>
    }
    

    使用示例

    //
    //  RequestLoadingPlugin.swift
    //  
    //
    //  Created by bruce yao on 2019/1/25.
    //  Copyright . All rights reserved.
    //
    
    import UIKit
    import Foundation
    import MBProgressHUD
    import Moya
    import Result
    
    class RequestLoadingPlugin: PluginType {
        
        func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
            print("prepare")
            var mRequest = request
            mRequest.timeoutInterval = 20
            return mRequest
        }
        
        func willSend(_ request: RequestType, target: TargetType) {
            print("开始请求")
            // 显示loading
        }
        
        func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
            print("结束请求")
    		// 关闭loading
            
           guard case Result.failure(_) = result else {
                let respons = result.value
                let dic: Dictionary<String, Any>? = try? JSONSerialization.jsonObject(with: respons!.data, options: .mutableContainers) as! Dictionary<String, Any>
                
                if dic != nil {
                    if dic?.keys.contains("code") == true {
                        if dic?["code"] as! Int == 700 {
                            print("Token 失效")
                        }
                    }
                }
                return
            }
            let errorReason: String = (result.error?.errorDescription)!
            print("请求失败:\(errorReason)")
            var tip = ""
            if errorReason.contains("The Internet connection appears to be offline") {
                tip = "网络不给力,请检查您的网络"
            }else if errorReason.contains("Could not connect to the server") {
                tip = "无法连接服务器"
            }else {
               tip = "请求失败"
            }
            /// 使用tip文字 进行提示
        }
    }
    
    
    展开全文
  • Moya ObjectMapper的基本使用方法
  • swift moya和ObjectMapper

    2018-05-05 00:47:13
    使用moya主要是因为网上说这是一个比较推荐的swift开源项目,当一开始学习时看见使用说明就有点扭头要走的冲动,本来一个简单的客户端http request代码分成了好多小块来处理,不过看在有名气的份上还是选择用它。...

    Moya


    使用moya主要是因为网上说这是一个比较推荐的swift开源项目,当一开始学习时看见使用说明就有点扭头要走的冲动,本来一个简单的客户端http request代码分成了好多小块来处理,不过看在有名气的份上还是选择用它。稍试用了一下发现这其实就像一个web服务器框架,按它的规则往里面填空就可以了,只不过我们平常很少在http客户端使用类似的框架。

    另外吐槽一下rxswift,这是因为moya也支持rxswift才想起来的。说实话虽然对于rxswift不怎么了解但是崇尚简单的我觉得学习rxswift就是多此一举,本来连swift我都觉得有点繁琐,没事还搞这么重的一层框架干嘛,非得在一种新语言里搞另一种编程范式,真是吃饱了撑的。

    Swift - 网络抽象层库Moya的使用详解1(安装配置、基本用法)
    Swift - 网络抽象层库Moya的使用详解2(请求参数说明)
    Swift - 网络抽象层库Moya的使用详解3(请求成功、失败的结果处理)
    Swift - 网络抽象层库Moya的使用详解4(单文件上传:文件流方式)
    Swift - 网络抽象层库Moya的使用详解5(多文件上传:MultipartFormData方式)
    Swift - 网络抽象层库Moya的使用详解6(文件下载、资源下载器)
    Swift - 网络抽象层库Moya的使用详解7(多个target使用同一个Provider)
    Swift - 网络抽象层库Moya的使用详解8(创建自定义插件)

    ObjectMapper


    Swift - 使用ObjectMapper实现模型转换1(JSON与Model的相互转换)
    Swift - 使用ObjectMapper实现模型转换2(StaticMappable协议)
    Swift - 使用ObjectMapper实现模型转换3(高级用法)
    Swift - 使用ObjectMapper实现模型转换4(与Alamofire结合使用)

    展开全文
  • MoyaSwift开发中起着重要的网络交互作用,但是还有不如之处,比如网络不可用时,返回的 Response 为 nil,这时还得去解析相应的 Error Codable 可以帮助我们快速的解析数据,但是一旦声明的属性类型与json中的不...
  • Swift - moya学习笔记

    2017-09-12 08:57:08
    本文主要是练习Moya的熟练使用简单的网络请求
  • 方法一: import Foundationimport ObjectMapperimport Moyaimport FTIndicatorstruct RejectModel : Codable { var id = 0 var projectnm = "" var requestdt = "" var createdAt = "...
  • 使用Alamofire进行网络请求的时候,相信大部分的同学都会封装一个抽象的NetworkLayer,如"APIManager" 或者 "NetworkModel"等等。但是位置业务功能增加,会渐渐混合各种请求,不够清晰,而Moya能很好地解决这类...
  • 踩坑踩了4天总算把基于Moya的网络框架搭建完毕 看网上关于Moya的教程不太多,大多都是一样的,还有一些年久失修。这里专门讲讲关于moya的搭建及容易遇到的一些坑。 重要的东西放到最前面 1.最好的教材是官方文档和...
  • 项目Demo地址 打造swift网络框架 准备工作 使用CocoaPods工具Pod需要... pod 'Moya/RxSwift' pod 'HandyJSON', '~> 5.0.0-beta.1' 创建文件 APIManager // // APIManager.swift // SwiftNetWorkHelper
  • 文章目录开源项目分析(SwiftHub)架构分析(一)1. SwiftHub项目简介2. SwiftHub项目采用的架构 开源项目分析(SwiftHub)架构分析(一) 1. SwiftHub项目简介 2. SwiftHub项目采用的架构 ...
  • RxSwift学习之十一 (Rxswift+Moya+Alamofire)
  • 网络请求是 App 中最常用的更能之一,除了 Apple 提供的 URLSession 之外,还有对其进行封装,功能更加强的的 Alamofire等强大的工具,尽管这样,我们依然会在自己的 App 中封装一套网络请求工具,以达到做网络请求时,代码...
  • Swift Moya

    2015-12-17 17:31:46
    但是,如果你直接使用的话,会使得各种网络请求操作分布很凌乱,所以我选择了巧神封装的YTKNetwork,很好用,有兴趣的可以看一下.当然你也可以自己组织封装. 这段代码就是LZ项目中的网络请求: NSDictionary *...
  • 对于swift4.2的网络请求的封装。包含链式,类AFN及对moya的封装。封装的功能包含:1.一次性处理请求指示器HUD 2.一次性处理请求状态码及错误弹窗 3.登录过期自动跳转到登录页等。 4.可以处理所有接口都要使用的公共...
  • 优雅的网络请求本人已写了一个开源的拿来及用的[Swift项目框架](https://github.com/liuniuliuniu/LLProgramFramework.Swift) 可以参考此框架来通篇阅读此文章更有帮助 有喜欢的还望送人玫瑰手留余香哦 当然这个拿...
  • 项目第一版网络框架用的是siesta,它的缓存与自动刷新确实很好用而且代码很简洁,但是...关于Moya使用介绍很多,我就不再赘述了。我主要记录一下我在使用过程中学到的处理方式。我的网络框架是搭着HandyJSON和RxSw...
1 2 3 4 5 ... 20
收藏数 395
精华内容 158
热门标签