app網(wǎng)絡(luò)請求封裝工具的實(shí)現(xiàn)缓呛,使用Moya+KakaJSON+PromiseKit,代碼如下:
創(chuàng)建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):
//參數(shù)加密
let encyParams = KoomeRequest.share.encyDis(parameters: params)
return .requestParameters(parameters: encyParams, encoding: JSONEncoding.default)
// default:
// return .requestPlain
}
/*
如果是圖片等資源文件上傳用這個(gè)
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)!
}
}
創(chuàng)建請求主工具
//
// 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()
//通過插件的方式監(jiān)聽網(wǎng)絡(luò)狀態(tài)
let networkPlugin = NetworkActivityPlugin { (type,target) in
switch type {
case .began:
print("顯示loading")
case .ended:
print("隱藏loading")
}
}
/// 網(wǎng)絡(luò)請求的基本設(shè)置,這里可以拿到是具體的哪個(gè)網(wǎng)絡(luò)請求葫男,可以在這里做一些設(shè)置
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
}
/// 網(wǎng)絡(luò)請求的設(shè)置
private let requestClosure = { (endpoint: Endpoint, done: MoyaProvider<KoomeServer>.RequestResultClosure) in
do {
var request = try endpoint.urlRequest()
// 設(shè)置請求時(shí)長
request.timeoutInterval = 20
// 打印請求參數(shù)
if let requestData = request.httpBody {
print("請求的url:\(request.url!)" + "\n" + "\(request.httpMethod ?? "")" + "發(fā)送參數(shù)" + "\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")")
} else {
print("請求的url:\(request.url!)" + "\(String(describing: request.httpMethod))")
}
if let header = request.allHTTPHeaderFields {
print("請求頭內(nèi)容\(header)")
}
done(.success(request))
} catch {
done(.failure(MoyaError.underlying(error, nil)))
}
}
//參數(shù)加密
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
//設(shè)置moya 配置
let provider = MoyaProvider<KoomeServer>(endpointClosure: endpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false)
provider.request(api) { result in
switch result{
case .success(let response):
// 解析數(shù)據(jù)
if let json = try? response.mapJSON() {
// 解析json
let resultModel: RequestResultModel<T> = self.parsingJson(json as! [String : Any])
// 后臺(tái)code!=200, 走錯(cuò)誤處理
guard resultModel.isSuccess else {
if resultModel.code == "-5" {
// 臨時(shí)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
}
}
}
}
/// 參數(shù)加密
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分多個(gè)人多個(gè)模塊可以使用甘有,模塊化管理接口,比如 用戶登陸棍现、首頁为黎、我的邮丰,這邊舉例 創(chuàng)建一個(gè)用戶請求, 傳入要解析的model
RequestResultModel 長這樣
class RequestResultModel<T: Convertible>{
var code = ""
/// 解密后的json, 如果T是RequestStringModel則是后臺(tái)返回的參數(shù)
var data = ""
var msg = ""
var sign = ""
/// 解析數(shù)據(jù)格式[key: value]
var model: T?
/// 解析數(shù)據(jù)格式[[key: value]]
var modelArray: [T]?
/// 把json解析成model
func pasringModel() {
// RequestStringModel 字符串?dāng)?shù)據(jù)不必再解析, 數(shù)據(jù)在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 {
}