app网络请求封装工具的实现,使用Moya+KakaJSON+PromiseKit,代码如下:
创建Server配置http :
//
// KoomeApi.swift
// know
//
// Created by Debug.s on 2022/4/26.
//
import Foundation
import Moya
import Alamofire
/// APP版本
public var appVersion: String {
get {
return "1.0.0"
}
}
enum KoomeServer {
//登陆
case loginApp(params: [String: String])
//注册
case register(params: [String: String])
// 注册保存用户信息
case registerUserInfo(params: [String: String])
}
extension KoomeServer : TargetType{
var path: String {
switch self{
case .loginApp:
return "/user/login"
case .register:
return "/user/register"
case .registerUserInfo:
return "/user/registerUserInfo"
}
}
var method: Moya.Method {
switch self{
case .loginApp,.register:
return .post
case .registerUserInfo:
return .get
}
}
var task: Task {
switch self{
case .loginApp(let params),.register(let params),.registerUserInfo(let params):
//参数加密
let encyParams = KoomeRequest.share.encyDis(parameters: params)
return .requestParameters(parameters: encyParams, encoding: JSONEncoding.default)
// default:
// return .requestPlain
}
/*
如果是图片等资源文件上传用这个
let formData = MultipartFormData(provider: .data(imgDate), name: "file",
fileName: "hangge.png", mimeType: "image/png")
return .uploadCompositeMultipart([formData], urlParameters: parameters)
*/
}
var headers: [String : String]? {
return [
"h": appVersion,
"Accept": "application/json",
"Content-Type": "application/json",
"Accept-Language": "en-US",
]
}
public var baseURL: URL {
return URL(string: HttpURLType.user.url)!
}
var parameterEncoding: ParameterEncoding {
return JSONEncoding.default // Send parameters as JSON in request body
}
var sampleData: Data {
return "".data(using: .utf8)!
}
}
创建请求主工具
//
// KoomeRequest.swift
// know
//
// Created by Debug.s on 2022/4/26.
//
import Foundation
import Moya
import Alamofire
import PromiseKit
import KakaJSON
class KoomeRequest {
static let share = KoomeRequest()
//通过插件的方式监听网络状态
let networkPlugin = NetworkActivityPlugin { (type,target) in
switch type {
case .began:
print("显示loading")
case .ended:
print("隐藏loading")
}
}
/// 网络请求的基本设置,这里可以拿到是具体的哪个网络请求,可以在这里做一些设置
private let endpointClosure = {(target: TargetType) -> Endpoint in
let url = target.baseURL.absoluteString + target.path
var task = target.task
var endPoint = Endpoint(url: url,
sampleResponseClosure: { .networkResponse(200, target.sampleData) },
method: target.method,
task: task,
httpHeaderFields: target.headers)
if let apiTarget = target as? MultiTarget,
let tar = apiTarget.target as? KoomeServer {
print(tar)
}
return endPoint
}
/// 网络请求的设置
private let requestClosure = { (endpoint: Endpoint, done: MoyaProvider<KoomeServer>.RequestResultClosure) in
do {
var request = try endpoint.urlRequest()
// 设置请求时长
request.timeoutInterval = 20
// 打印请求参数
if let requestData = request.httpBody {
print("请求的url:\(request.url!)" + "\n" + "\(request.httpMethod ?? "")" + "发送参数" + "\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")")
} else {
print("请求的url:\(request.url!)" + "\(String(describing: request.httpMethod))")
}
if let header = request.allHTTPHeaderFields {
print("请求头内容\(header)")
}
done(.success(request))
} catch {
done(.failure(MoyaError.underlying(error, nil)))
}
}
//参数加密
public func encyDis(parameters:[String: String]) -> [String: String]{
return paramsEncrypt(parameters)!
}
//请求方法
public func request<T: Convertible>(api:KoomeServer) -> Promise<RequestResultModel<T>> {
return Promise<RequestResultModel<T>> { resolver in
//设置moya 配置
let provider = MoyaProvider<KoomeServer>(endpointClosure: endpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false)
provider.request(api) { result in
switch result{
case .success(let response):
// 解析数据
if let json = try? response.mapJSON() {
// 解析json
let resultModel: RequestResultModel<T> = self.parsingJson(json as! [String : Any])
// 后台code!=200, 走错误处理
guard resultModel.isSuccess else {
if resultModel.code == "-5" {
// 临时token过期code
resolver.reject(RequestError(code: resultModel.code, data: resultModel.data, message: resultModel.msg))
} else if resultModel.code == "-6" {
// 禁用code
} else if resultModel.code == "-9" {
// 踢蹬code
} else {
resolver.reject(RequestError(code: resultModel.code, data: resultModel.data, message: resultModel.msg))
}
return
}
// 返回model
resolver.fulfill(resultModel)
} else {
resolver.reject(RequestError(code: RequestErrorType.parsing.rawValue, data: "", message: "Data parsing error"))
}
case .failure(let error):
debugPrint(error)
resolver.reject(RequestError(code: RequestErrorType.network.rawValue, data: "", message: "Network request error"))
break
}
}
}
}
/// 参数加密
private func paramsEncrypt(_ parameters: Any? = nil) -> [String: String]? {
// removerHeaders(name: "sign")
// rsa加密
if let params = parameters,
let jsonStr = CommonUtil.jsonStr(obj: params),
let encryptStr = EncryptUtil.encryptRSA(str: jsonStr) {
return ["sign": encryptStr]
}
return [:]
}
/// 解析json
private func parsingJson<T: Convertible>(_ json: [String: Any]) -> RequestResultModel<T> {
let resultModel = json.kj.model(RequestResultModel<T>.self)
if stringIsEmpty(str: resultModel.data) {
return resultModel
}
// 解密
let key = EncryptUtil.decryptAES128(str: resultModel.sign) ?? ""
var decryptStr = EncryptUtil.decryptDES(str: resultModel.data, key: key) ?? ""
if decryptStr.hasPrefix("\"") && decryptStr.hasSuffix("\"") {
if let i = decryptStr.firstIndex(of: "\"") {
decryptStr.remove(at: i)
}
if let i = decryptStr.lastIndex(of: "\"") {
decryptStr.remove(at: i)
}
}
resultModel.data = decryptStr
resultModel.pasringModel()
#if DEBUG
if let obj = CommonUtil.jsonObject(json: decryptStr) {
PLog(obj)
}
#endif
return resultModel
}
}
如果app分多个人多个模块可以使用,模块化管理接口,比如 用户登陆、首页、我的,这边举例 创建一个用户请求, 传入要解析的model
RequestResultModel 长这样
class RequestResultModel<T: Convertible>{
var code = ""
/// 解密后的json, 如果T是RequestStringModel则是后台返回的参数
var data = ""
var msg = ""
var sign = ""
/// 解析数据格式[key: value]
var model: T?
/// 解析数据格式[[key: value]]
var modelArray: [T]?
/// 把json解析成model
func pasringModel() {
// RequestStringModel 字符串数据不必再解析, 数据在data
guard !stringIsEmpty(str: data),
T.self != RequestStringModel.self else {
return
}
// 解析model或者modelArray
let obj = CommonUtil.jsonObject(json: data)
if obj is [String: Any] {
model = data.kj.model(T.self)
} else if obj is [[String: Any]] {
modelArray = data.kj.modelArray(T.self)
}
}
}
//
// KoomeUserRequest.swift
// know
//
// Created by Debug.s on 2022/4/26.
//
import Foundation
import PromiseKit
class KoomeUserRequest{
/// 注册
static public func register(code: String, emailAccount: String, password: String) -> Promise<RequestResultModel<RequestStringModel>> {
let params: [String: String] = [
"device": UIDevice.current.name,
"deviceId": UIDevice.current.identifierForVendor?.uuidString ?? "",
"code": code,
"emailAccount": emailAccount,
"password": password.md5()
]
return KoomeRequest.share.request(api: .registerUserInfo(params: params))
}
}
使用
KoomeUserRequest.register(code: "1234", emailAccount: "3899379@qq.com", password: "1234qwer").done { result in
//在这边处理 result 逻辑
}.catch { _ in
}.finally {
}