188 lines
6.3 KiB
Swift

//
// SPNetwork.swift
// ShortPlay
//
// Created by on 2025/4/8.
//
import UIKit
import Moya
import SmartCodable
///
let SPNetworkCodeSucceed = 200
class SPNetwork: NSObject {
///
private static var awaitDataArr: [Any] = []
private static var group = DispatchGroup()
private static var queue: DispatchQueue = DispatchQueue(label: "bcRequestQueue", attributes: .concurrent)
static let semaphore = DispatchSemaphore(value: 1) // 1
static let provider = MoyaProvider<SPApi>(requestClosure: CustomApiTimeoutClosure)
static func request<T>(parameters: SPNetworkParameters, completion: ((_ response: SPNetworkResponse<T>) -> Void)?) {
if SPLoginManager.manager.token == nil {
SPLoginManager.manager.requestVisitorLogin(completer: nil)
}
if SPLoginManager.manager.isRefreshingToken && parameters.path != "/customer/register" {
var loding = true
while loding {
if !SPLoginManager.manager.isRefreshingToken {
loding = false
}
RunLoop.current.run(mode: .default, before: Date.distantFuture)
}
}
_request(parameters: parameters, completion: completion)
}
@discardableResult
static func _request<T>(parameters: SPNetworkParameters, completion: ((_ response: SPNetworkResponse<T>) -> Void)?) -> Cancellable {
if parameters.isLoding {
// ETHUD.show()
}
return provider.requestCustomJson(.request(parameters: parameters)) { (result) in
if parameters.isLoding {
// ETHUD.dismiss()
}
guard let completion = completion else {return}
_resultDispose(parameters: parameters, result: result, completion: completion)
}
}
private static func _resultDispose<T>(parameters: SPNetworkParameters, result: Result<Moya.Response, MoyaError>, completion: ((_ response: SPNetworkResponse<T>) -> Void)?) {
switch result {
case .success(let response):
let code = response.statusCode
if code == 401 || code == 402 || code == 403 {
// var data = SPNetworkData<T>()
// data.parameters = parameters
// data.completion = completion
//
// awaitDataArr.append(data)
// awaitDataArr.first as? SPNetworkData<T>
if !SPLoginManager.manager.isRefreshingToken {
SPLoginManager.manager.requestVisitorLogin {
if let _ = SPLoginManager.manager.token {
self.request(parameters: parameters, completion: completion)
}
}
} else {
if parameters.path != "/customer/register" {
// while SPLoginManager.manager.isRefreshingToken {
// RunLoop.current.run(mode: .default, before: Date.distantFuture)
// }
// if let _ = SPLoginManager.manager.token {
// self.request(parameters: parameters, completion: completion)
// }
}
}
return
}
do {
let tempData = try response.mapString()
spLog(message: parameters.parameters)
spLog(message: parameters.path)
DispatchQueue.global().async {
let response: SPNetworkResponse<T> = _deserialize(data: tempData)
DispatchQueue.main.async {
if response.code != SPNetworkCodeSucceed {
if parameters.isToast {
SPToast.show(text: response.msg)
}
}
completion?(response)
}
}
} catch {
var res = SPNetworkResponse<T>()
res.code = -1
if parameters.isToast {
SPToast.show(text: "Error".localized)
}
completion?(res)
}
case .failure(let error):
spLog(message: error)
var res = SPNetworkResponse<T>()
res.code = -1
if parameters.isToast {
SPToast.show(text: "Error".localized)
}
completion?(res)
break
}
}
///
static private func _deserialize<T>(data: String) -> SPNetworkResponse<T> {
var response: SPNetworkResponse<T>?
let time = Date().timeIntervalSince1970
if let decrypted = SPCryptService.decrypt(data) {
spLog(message: decrypted)
response = SPNetworkResponse<T>.deserialize(from: decrypted)
response?.rawData = decrypted
}
spLog(message: Date().timeIntervalSince1970 - time)
if let response = response {
return response
} else {
var response = SPNetworkResponse<T>()
response.code = -1
response.msg = "Error".localized
return response
}
}
}
extension MoyaProvider {
@discardableResult
func requestCustomJson(_ target: Target, callbackQueue: DispatchQueue? = nil, completion: Completion?) -> Cancellable {
return request(target, callbackQueue: callbackQueue) { (result) in
guard let completion = completion else {return}
completion(result)
}
}
}
let CustomApiTimeoutClosure = {(endpoint: Endpoint, closure: MoyaProvider<SPApi>.RequestResultClosure) -> Void in
if var urlRequest = try? endpoint.urlRequest() {
///
urlRequest.cachePolicy = .reloadIgnoringCacheData
urlRequest.timeoutInterval = 30
closure(.success(urlRequest))
} else {
closure(.failure(MoyaError.requestMapping(endpoint.url)))
}
#if DEBUG ///
//print(try? endpoint.urlRequest() )
#endif
}