Moya+BetterCodable+PromisesKit网络封装

251 阅读2分钟

Moya+BetterCodable+PromisesKit网络封装 模型层使用BetterCodable 代码如下

import Foundation
import BetterCodable
public struct BaseModel<T: Codable>: Codable {

    @LosslessValue var code: String = ""

    @LossyOptional var msg: String?

    @LossyOptional var message: String?

    @LossyOptional var token: String?

    @LossyOptional var loginUser: T?

    @LossyOptional var data: T?

}
public struct BaseArrayModel<T: Codable>: Codable {

    @LosslessValue var code: String = ""

    @LossyOptional var msg: String?

    @LossyOptional var message: String?

    @LossyOptional var data: [T]?

}

MoyaApi部分

import Foundation
import Moya

enum MoyaApi {
    case login(param: [String: Any])
}

extension MoyaApi: TargetType {
    var baseURL: URL {
        return URL.init(string: "http:xxxxxxxxx")!

    }
    var path: String {
        switch self {
        case .login:
            return "xxxxxx"
        }
    }
    var method: Moya.Method {
        switch self {
        case    .login
            return .post
        }
    }
    var sampleData: Data {
        return "".data(using: String.Encoding.utf8)!
    }
    var task: Task {
        switch self {
        case .login(let param)
            return getTask(self, param)
        }
    }
    var headers: [String: String]? {
        var headers = ["Content-Type": "application/json"]
        return headers
    }

}

// **MARK: 设置通用的TASK**

func getTask(_ target: TargetType, _ params: [String: Any] = [:]) -> Task {
    switch target.method {
    case .get:
        return .requestParameters(parameters: params, encoding: URLEncoding.default)
    case .post:
        return .requestParameters(parameters: params, encoding: JSONEncoding.default)
    default:
        return .requestPlain
    }

}

网络部分封装

import Foundation
import Moya
import Alamofire
import Promises
private var requestTimeOut: Double = 60

// **MARK: - --网络请求的基本设置**

private let myEndpointClosure = { (target: TargetType) -> Endpoint in
    let url = target.baseURL.absoluteString+target.path
    var task = target.task
    // 添加公共参数
    switch target.task {
    case .requestParameters(var parameters, let encoding):
        task = .requestParameters(parameters: signParameters(parameters), encoding: encoding)
    case let .uploadMultipart(multipartData):
        task = .uploadCompositeMultipart(multipartData, urlParameters: signParameters([:]))
    default:
        break
    }
    var endpoint = Endpoint(
        url: url,
        sampleResponseClosure: { .networkResponse(200, target.sampleData) },
        method: target.method,
        task: task,
        httpHeaderFields: target.headers
    )
    return endpoint
}
// 公共参数

private func signParameters(_ parameter: [String: Any]) -> [String: Any {
    var mDict: [String: Any = [:]
    parameter.forEach { mDict[$0.key] = $0.value }
    return mDict
}

// 网络请求的设置
private let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in
    do {
        var request = try endpoint.urlRequest()
        // 设置请求时长
        request.timeoutInterval = requestTimeOut
        done(.success(request))
    } catch {
        done(.failure(MoyaError.underlying(error, nil)))
    }
}
// 网络请求开始到结束状态监听

private let networkPlugin = NetworkActivityPlugin.init { changeType, _ in
    switch changeType {
    case .began:
        print("开始请求网络")
    case .ended:
        print("结束")
    }
}
// **MARK: - -- 创建网络请求对象**
let CLProvider = MoyaProvider<MultiTarget>(endpointClosure: myEndpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false)

// **MARK: 判断是不是有网络**

public func hasNetWork() -> Bool {
    let reachable = Alamofire.NetworkReachabilityManager(host: "www.apple.com")
    return reachable?.isReachable ?? false
}

public func request<T: Codable>(_ target: TargetType, needShowHud: Bool = true, showErrorMsg: Bool = true) -> Promise<BaseModel<T>?> {
    if needShowHud {
    }
    return Promise<BaseModel<T>?>{ resolve,reject  in
        CLProvider.request(MultiTarget(target)) { result in
            // 隐藏loading
            if needShowHud {
               
              }
            switch result {
            case let .success(response):
                do {
                    let model = try JSONDecoder.init().decode(BaseModel<T>.self, from: response.data)
                    let message = model.msg ?? model.message
                    if model.code == "2001" {
                        let error = NSError(domain: message ?? "", code: 2001)
                        reject(error)

                    }
                    if  model.code == "0" {
                        resolve(model)
                    } else {
                        if showErrorMsg,let message = message {

                        }
                        let error = NSError(domain: message ?? "", code: Int(model.code) ?? 0)
                        reject(error)
                    }
                } catch {
                    if showErrorMsg {
                    }
                    reject(error)
                }

            case let .failure(error):
                if showErrorMsg {

                }
                reject(error)
            }

        }

    }

}

public func requestList<T: Codable>(_ target: TargetType, needShowHud: Bool = true, showErrorMsg: Bool = true) -> Promise<BaseArrayModel<T>?> {

    if needShowHud {

    }
    return Promise<BaseArrayModel<T>?>{ resolve,reject  in
        CLProvider.request(MultiTarget(target)) { result in
            // 隐藏loading

            if needShowHud {

               }
            switch result {
            case let .success(response):
                do {
                    let model = try JSONDecoder.init().decode(BaseArrayModel<T>.self, from: response.data)
                    let message = model.msg ?? model.message
                    if model.code == "2001" {
                        reject(error)
                    }
                    if model.code == "0" {
                        resolve(model)
                    } else {
                        if showErrorMsg,let message = message {

                        }
                        let error = NSError(domain: message ?? "", code: Int(model.code) ?? 0)
                        reject(error)
                    }

                } catch {
                    if showErrorMsg {

                    }
                    reject(error)
                }
            case let .failure(error):
                if showErrorMsg {
                
                }
                reject(error)
            }
        }

    }

}

使用方法:

request(MoyaApi.login(param: ["mobile":"xxxxxxx","password":"xxxxxx"])).then{ (data:BaseModel<CLLoginModel>?) in
            guard let data = data?.data else{return}

        }