美文网首页
Moya使用,看我就行了

Moya使用,看我就行了

作者: 门前的那颗樱桃树 | 来源:发表于2019-02-23 11:28 被阅读0次

    Moya是一个在GitHub上Star10k加的框架了,相信他的实力已经不言而喻了。

      笔者是一个次开始使用swift的OC开发者,对于一些swift使用,还是很懵逼的。只能去慢慢探索吧。由于对Objective-C的使用,很多思维方式被限制了,使用起swift很蛋疼(个人感觉)。

      在下决定学习Moya之前,我已经好多次翻看这个使用说明,然而都是中途放弃了🤣

    然后我去下载了Moya库,找到他们的中文文档,虽然文档很清晰,对于我这样的才开始写swift和接触Moya的还是很茫然的。和Objective-C我参数传进去一个对象,返回结果也是一个对象,还是有很大出入的😹。
    Moya的中文文档.png
    开始阅读,我们从哪里开始开呢,当然是从readme开始了
    # 示例
    * [基本用法](Basic.md)
    * [Multipart upload](MultipartUpload.md)
    * [Use MultiTarget for multiple Targets using the same Provider](MultiTarget.md)
    * [资源下载设置](Assets.md)
    * [Alamofire自动验证](AlamofireValidation.md)
    ## 自定义Endpoints
    * [可选的请求参数](OptionalParameters.md)
    ## 包装适配器
    * [把 **request -> result**流程,包装到你自己的适配器中](WrappingInAdapter.md)
    ## 错误处理
    * [处理不同错误类型](ErrorTypes.md)
    ## 插件
    * [创建自定义插件](CustomPlugin.md)
    * [创建授权插件](AuthPlugin.md)
    

    我们一步一步的来先实现基本用法,然后再去完善成我们要求的那样。

    第一步:根据Moya的基本用法走一波

      跟着基本用法一步一步创建。我创建的文件名为NetworkTools.swift这个我用的是 干货集中营的API。
      我先创建一个NetworkTools的枚举,然后这个枚举必须遵循TargetType协议,那我们来看看这个协议到底有哪些东西呢?包括如下的协议内容:

    /// 用于定义“MoyaProvider”所需规范的协议。
    public protocol TargetType {
        /// 请求的 baseURL
        var baseURL: URL { get }
        /// 拼接 baseURL 成为完整的 URL 路径 
        var path: String { get }
        /// 请求中使用的HTTP方法(一般为 .post和 .get)
        var method: Moya.Method { get }
        /// 提供用于测试的数据 
        var sampleData: Data { get }
        /// 要执行的HTTP任务的类型。
        var task: Task { get }
        /// 对请求执行的验证类型  默认设置是 .none
        var validationType: ValidationType { get }
        /// 请求中header
        var headers: [String: String]? { get }
    }
    public extension TargetType {
        /// 对请求执行的验证类型  默认设置是 .none
        var validationType: ValidationType {
            return .none
        }
    }
    
    我们更具他的协议,写一个简单的Demo如下:
    import UIKit
    import Moya
    
    let NetworkProvider = MoyaProvider<NetworkTools>()
    
    enum NetworkTools {
        case today
    }
    extension NetworkTools: TargetType {
        var baseURL: URL {
             return URL(string: "http://gank.io/api/")!
        }
        var path: String {
           return "today"
        }
        var method: Moya.Method {
            return .get
        }
        var sampleData: Data {
            return "{}".data(using: String.Encoding.utf8)!
        }
        var task: Task {
            let parmeters = [String : Any]()
            return .requestParameters(parameters: parmeters, encoding: URLEncoding.default)
        }
        var headers: [String : String]? {
            let header = ["Content-Type" : "application/json; charset=utf-8"]
            return header
        }
    }
    
    在控制器中代码如下
    class MMPCollectionVC: BaseViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            NetworkProvider.request(.today) { result in
                switch result {
                case let .success(moyaResponse):
                    let data = moyaResponse.data
                    let statusCode = moyaResponse.statusCode
                    TSLog(data)
                    TSLog(statusCode)
                    do {
                        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
                        TSLog(json)
                    } catch {
                        TSLog(statusCode)
                    }
                    
                case let .failure(error):
                    TSLog(error)
                }
            }
        }
    }
    
    打印部分结果
    🎈 -[MMPCollectionVC.swift viewDidLoad() line:21] 🎈 
     33772 bytes
    🎈 -[MMPCollectionVC.swift viewDidLoad() line:22] 🎈 
     200
    🎈 -[MMPCollectionVC.swift viewDidLoad() line=25] 🎈 
     {
        error = 0,
        results = {
            Android = [
                {
                    used = 1,
                    createdAt = "2018-12-04T06:44:18.364Z",
                    images = [
                        "http://img.gank.io/0cd8baa4-7d96-40fb-ab0c-4b3668a7ac4d",
                        "http://img.gank.io/35066fc9-4c67-498d-b9e1-f8e3ca7410e1",
                        "http://img.gank.io/ad8b369e-c643-4631-afdd-4466aab4f7fd",
                        "http://img.gank.io/101d45df-c66b-4610-809a-734fbca99967",
                        "http://img.gank.io/d8755a02-fe71-4562-ac9f-4d7d6b0d3358",
                    ],
                    url = "https://github.com/yangchong211/YCVideoPlayer",
                    publishedAt = "2019-02-13T03:26:06.640Z",
                    who = "fingdo",
                    _id = "5c0622429d2122308e7445cf",
                    source = "web",
                    type = "Android",
                    desc = "一个基于ijkplayer的完整视频播放器封装,支持自定义,拓展性强,已经用于实际开发中",
                },
                {
                    used = 1,
                    createdAt = "2019-01-03T11:25:59.115Z",
                    images = [
                        "https://ww1.sinaimg.cn/large/0073sXn7ly1fze96rdfhmg308w0ft7wh",
                        "https://ww1.sinaimg.cn/large/0073sXn7ly1fze96s6tdag308w0ftjvw",
                    ],
    

    2019年04月22日

    HandyJSON 配合 Moya请求

    在正常的网络请求过程中,我们请求数据时,不想那么麻烦:
    目标:1、请求时传入model 类型
       2、返回数据,直接返回传入的model

    下面代码就是我登录请求的例子:
    我传入 ZSLoginModel,
    返回的时候就是ZSLoginModel

    class ZSLoginViewModel: BaseViewModel {
        var loginModel: ZSLoginModel?
    }
    
    extension ZSLoginViewModel {
        func loginNetworking(params:[String: Any]) -> Void {
            loginProvider.rx.request(.login(params: params)).asObservable().mapModel(type: ZSLoginModel.self).subscribe { (event) in
    
                switch event {
                case .next(let model):
                    self.loginModel = model
                    ZSRealm_Tool.instance.saveLoginModel(model: model)
                case .completed:
                    self.updataBlock?()
                case .error(let error):
                    TSLog(error)
                }
                }.disposed(by: disposeBag)
        }
    }
    

    我们需要给ObservableType 和 Response 加写扩展,我们就可以达到这个效果

    import HandyJSON
    import Moya
    import RxSwift
    import SwiftyJSON
    
    /// 数据 转 模型
    extension ObservableType where E == Response {
        public func mapModel<T: HandyJSON>(type: T.Type)->Observable<T> {
            return flatMap { response -> Observable<T> in
                return Observable.just(response.mapModel(T.self))
            }
        }
    }
    /// 数据 转 模型
    extension Response {
        func mapModel<T: HandyJSON>(_ type: T.Type) -> T {
            let json = JSON(data)["result"].dictionaryObject
            return JSONDeserializer<T>.deserializeFrom(dict: json)!
        }
    }
    

    请求时,的加载动画

    我们往往会在加载的过程中,需要有一个加载的动画(MBProgressHUDNVActivityIndicatorView都是不错的选择)
    我们需要做的就是写自己的插件。文档中的CustomPlugin.md

    /// 自定义插件
    public final class NetworkLoadingPlugin: PluginType {
        public func willSend(_ request: RequestType, target: TargetType) {
            TSLog("开始请求")
        }
        public func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType) {
            TSLog("请求结束")
        }
    }
    

    你可以把这个,和上面的扩展放到一起,有助于你的管理

    image.png

    那么这样,你就距离你理想的网络请求有进一步了,对于加载动画,你可以根据你自己的需求写入。然而笔者在这里留下了一个坑,也是我读文档是,遇到的。你是不是感觉didReceive这个方法没有调用。你可以导入Result这个之后再试一试。哈哈哈😁

    这样可能还是不满足我们的需求啊~那我就应该继续完善,不要怂!!!多读几遍,自然OK!

    相关文章

      网友评论

          本文标题:Moya使用,看我就行了

          本文链接:https://www.haomeiwen.com/subject/oywuyqtx.html