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}
}