swift网络请求封装(Moya)

7 篇文章 0 订阅
5 篇文章 0 订阅

最近打算自己写个项目练练手,在弄到网络请求这块,发现之前用的都不是特别好用,于是想着还是自己手动封装一下,于是如下:
所用的第三方库:

pod 'Moya'
pod 'Reachability'
pod 'MBProgressHUD'
pod 'HandyJSON'
pod 'Result'

在这里插入图片描述
对于moya用法大家参照官方文档我就直接cv了,如下:
新建类NetManager

//
//  NetManager.swift
//  
//
//  Created by  on 2022/4/12.
//

import Moya
import MBProgressHUD
import HandyJSON
import Result
import CWLog

//MARK: loading插件,组合API请求,可在请求中自动补充loading
let LoadingPlugin = NetworkActivityPlugin { (type, target) in
//    guard let vc = topVC else {return}
    switch type {
    case .began: break
    case .ended: break
    }
    
}

//MARK: 超时中间件
let timeoutClosure = {(endpoint: Endpoint, closure: MoyaProvider<NetManager>.RequestResultClosure) -> Void in
    
    if var urlRequest = try? endpoint.urlRequest() {
        urlRequest.timeoutInterval = 20
        closure(.success(urlRequest))
    } else {
        closure(.failure(MoyaError.requestMapping(endpoint.url)))
    }
}

//MARK: 无loading请求
let ApiProvider = MoyaProvider<NetManager>(requestClosure: timeoutClosure)
//MARK: 有loading请求
let ApiLoadingProvider = MoyaProvider<NetManager>(requestClosure: timeoutClosure, plugins: [LoadingPlugin])


enum NetManager {
    case Recommend(device_id: String, model: String,sTime: String,systemVersion: String, target: String, time: String, version: String)
    case searchHot//搜索热门
    
}

extension NetManager: TargetType {
    var path: String {
        switch self {
        case .Recommend:
            return "/Recommend/head"
        case .searchHot:
            return "search/hotkeywordsnew"
        }
    }
    
    var method: Moya.Method {
        return .get
    }
    
    var task: Task {
        var paramters: [String : Any] = [:]
        switch self {
        case .Recommend(let device_id, let model, let sTime, let systemVersion, let target, let time, let version):
            paramters["device_id"] = device_id
            paramters["model"] = model
            paramters["sTime"] = sTime
            paramters["systemVersion"] = systemVersion
            paramters["target"] = target
            paramters["time"] = time
            paramters["version"] = version
        default:break
        }
        return .requestParameters(parameters: paramters, encoding: URLEncoding.default)
    }
    
    var sampleData: Data { return "".data(using: String.Encoding.utf8)! }
    
    var headers: [String : String]? {
        return nil
    }
    
    var baseURL: URL {
        return URL(string: "https://app.u17.com/v3/appV3_3/ios/phone")!
    }
    
}

//MARK: 请求结果解析模型
extension Response {
    func mapModel<T: HandyJSON>(_ type: T.Type)throws -> T {
        let jsonString = String(data: data, encoding: .utf8)
        CWLog(jsonString)
        guard let model = JSONDeserializer<T>.deserializeFrom(json: jsonString) else {
            throw MoyaError.jsonMapping(self)
        }
        return model
    }
}

//MARK: 统一请求封装
extension MoyaProvider {
    @discardableResult
    open func request<T: HandyJSON>(_ target: Target,
                                    model: T.Type,
                                    completion:((_ returnData: T?) -> Void)?
    ) -> Cancellable? {
        return request(target) { result in
            debugPrint(result.value)
            guard let completion = completion else {
                return
            }

            guard let returnData = try? result.value?.mapModel(ResponseData<T>.self) else {
                completion(nil)
                return
            }
            completion(returnData.data?.returnData)
        }
    }
}


以上就是其实就是moya简单的使用只不过对于请求的结果利用了HandyJSON进行了转化返回的结果直接就是model类型了
其中要注意一下:
所写的model类要按照HandyJSON规则去写如下:

struct QTitleModel : HandyJSON {
    var title: String? = nil
    var type: String? = nil
    var tag: String? = nil
    var search_hot: String? = nil
    var id: String? = nil
    var banner_id: String? = nil
    var is_recommend: String? = nil
    var url: String? = nil
}
extension Array: HandyJSON{}
struct ReturnData<T : HandyJSON>: HandyJSON {
    var message:String?
    var returnData: T?
    var stateCode: Int = 0
}

struct ResponseData<T : HandyJSON>: HandyJSON {
    var code : Int = 0
    var message: String?
    var data: ReturnData<T>?
}

其中的RseponseData在NetManager类中已使用,如果模型中有复杂的模型转换,只需将包含的key对用的value值对应为你所写的类即可
例如:数据中包含QTitleModel列表,那可这样写:

struct QTitleList: HandyJSON {
    var  returnData: [QTitleModel]?
}

使用:

/** 网络请求 */
extension HomeViewController {
    func loadData() {
        let device_id = "69EACCA0-47C8-40EE-835F-7C02D8105F93"
        let model = "iPhone%207%20Plus"
        let sTime = "1624922081"
        let systemVersion = "13.3.1"
        let target = "U17_3.0"
        let time = "1649726510"
        let version = "5.8.0"
        
        ApiLoadingProvider.request(NetManager.Recommend(device_id: device_id, model: model, sTime: sTime, systemVersion: systemVersion, target: target, time: time, version: version), model: Array<QTitleModel>.self) { returnData in
            self.titles = returnData!
            
        }
    }
}

简单粗暴!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~轻舟~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值