在网上找了一个他人封装的网络框架,只需要自己根据项目要求在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
}
}
}
网友评论