美文网首页
网络请求

网络请求

作者: 菲特峰 | 来源:发表于2020-07-19 17:53 被阅读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
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:网络请求

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