网络请求

2020-07-19  本文已影响0人  菲特峰
image.png

在网上找了一个他人封装的网络框架,只需要自己根据项目要求在MoyaConfig文件中修改配置即可,用起来非常方便
封装了请求Loading可以自动控制是否显示
自带了缓存处理

Moya的使用

//  moya的一个具体的接口实现

import Foundation
//import Moya

enum  DMAPI {
    //排行榜
    case rankList
    
    ///其他接口...
    case other1(param: String)
    case other2

}

// 补全【MoyaConfig 3:配置TargetType协议可以一次性处理的参数】中没有处理的参数
extension DMAPI: TargetType {
        var headers: [String : String]? {
            return ["Signtoken":UserInfo.defaultInfo().signToken ?? ""]
        }
    

    //1. 每个接口的相对路径
    //请求时的绝对路径是   baseURL + path
    var path: String {
        switch self {
        case .rankList:
            return "rank/list"
        case .other1:
            return ""
        case .other2:
            return ""
        }
    }

    //2. 每个接口要使用的请求方式
    var method: Moya.Method {
        switch self {
        case .rankList:
            return .post
        case .other1:
            return .post
        case .other2:
            return .get
        }
    }

    //3. Task是一个枚举值,根据后台需要的数据,选择不同的http task。
    var task: Task {
        var params: [String: Any] = [:]
        switch self {
        case .rankList:
            return .requestPlain
        case let .other1(param):
            params["param"] = param
        default:
            //不需要传参数的接口走这里
            return .requestPlain
        }
        return .requestParameters(parameters: params, encoding: URLEncoding.default)
    }
    
}

//  moya封装

import Foundation
//import Moya
import MBProgressHUD

public class HttpRequest {
    /// 使用moya的请求封装
    ///
    /// - Parameters:
    ///   - target: TargetType里的枚举值
    ///   - needHud: 错误信息是否弹窗
    ///   -needCache: 是否缓存
    ///   -cache: 需要单独处理缓存的数据时使用,(默认为空,使用success处理缓存数据)
    ///   - success: 成功的回调
    ///   - error: 连接服务器成功但是数据获取失败
    ///   - failure: 连接服务器失败
    public class func loadData<T: TargetType>(target: T,needHud:Bool = true, needCache: Bool = false, cache: ((Data) -> Void)? = nil, success: @escaping((Data) -> Void), failure: ((Int?, String) ->Void)? ) {
        
        let provider = MoyaProvider<T>(plugins: [
            RequestHandlingPlugin(),
            networkLoggerPlugin
            ])
        //如果需要读取缓存,则优先读取缓存内容
        if needCache, let data = SaveFiles.read(path: target.path) {
            //cache不为nil则使用cache处理缓存,否则使用success处理
            if let block = cache {
                block(data)
            }else {
                success(data)
            }
        }else {
            //读取缓存速度较快,无需显示hud;仅从网络加载数据时,显示hud。
            ProgressHUD.show()
        }
        
        provider.request(target) { result in
            ProgressHUD.hide()
            DLog("===========\(result)")
            switch result {
            case let .success(response):
                // ***********  这里可以统一处理状态码 ****
                //从json中解析出status_code状态码和message,用于后面的处理
                guard let model = try? JSONDecoder().decode(LFBaseModel.self, from: response.data) else {
                    //解析出错后,直接返回data
                    if response.statusCode == 200 {
                        success(response.data)
                    } else {
                         failure?(response.statusCode, "\(response.statusCode)")
                    }
                    return
                }
                
                //状态码:后台会规定数据正确的状态码,未登录的状态码等,可以统一处理。
                switch (model.generalCode) {
                case HttpCode.success.rawValue :
                    //数据返回正确
                    if needCache {
                        //缓存
                        SaveFiles.save(path: target.path, data: response.data)
                    }
                    success(response.data)
                case HttpCode.needLogin.rawValue:
                    //请重新登录
                    failure?(model.generalCode ,model.generalMessage)
                    DLog("请重新登录")

                    alertLogin(model.generalMessage)
                case HttpCode.bingWXCode.rawValue:
                    //绑定手机号
                    success(response.data)

                    //签名错误重新请求
                case HttpCode.signCode0.rawValue,HttpCode.signCode1.rawValue,HttpCode.signCode2.rawValue:
                        PXSGetSignTool.getSignToken()
                //跳转登录页
                case HttpCode.signCode3.rawValue,HttpCode.signCode4.rawValue,HttpCode.signCode5.rawValue,HttpCode.signCode6.rawValue,HttpCode.signCode7.rawValue,HttpCode.signCode8.rawValue:

                    DLog("请重新登录")
                    alertLogin(model.generalMessage)

                default:
                    ProgressHUD.hide()

                    //其他错误
                    failureHandle(failure: failure, stateCode: model.generalCode, message: model.generalMessage)

                }
            // ********************
            case let .failure(error):
                ProgressHUD.hide()
                let statusCode = error.response?.statusCode ?? 0
                let errorCode = "请求出错,错误码:" + String(statusCode)
                failureHandle(failure: failure, stateCode: statusCode, message: error.errorDescription ?? errorCode)

            }
        }
        
        //错误处理 - 弹出错误信息
        func failureHandle(failure: ((Int?, String) ->Void)? , stateCode: Int?, message: String) {
            if needHud {
                Alert.show(type: .error, text: message)
            }
            failure?(stateCode ,message)
        }
        
        //登录弹窗 - 弹出是否需要登录的窗口
        func alertLogin(_ title: String?) {
            //TODO: 跳转到登录页的操作:
            //清空数据
            LFNotice.post(notification: LFNotice.Notification.loginOut)
            //重新登录
            LFNotice.post(notification: LFNotice.Notification.needLogin)

        }
    }

    static let networkLoggerPlugin = NetworkLoggerPlugin(verbose: true, cURL: true, requestDataFormatter: { data -> String in
        return String(data: data, encoding: .utf8) ?? ""
    }) { data -> (Data) in
        do {
            let dataAsJSON = try JSONSerialization.jsonObject(with: data)
            let prettyData =  try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
            return prettyData
        } catch {
            return data
        }
    }
}

上一篇 下一篇

猜你喜欢

热点阅读