224 lines
7.5 KiB
Swift
224 lines
7.5 KiB
Swift
//
|
|
// SPNetwork.swift
|
|
// MoviaBox
|
|
//
|
|
// Created by 曾觉新 on 2025/4/8.
|
|
//
|
|
|
|
import UIKit
|
|
import Moya
|
|
import SmartCodable
|
|
|
|
///获取数据成功
|
|
let SPNetworkCodeSucceed = 200
|
|
|
|
class SPNetwork: NSObject {
|
|
|
|
///用来获取token的线程
|
|
private static let operationQueue = OperationQueue()
|
|
private static var tokenOperation: BlockOperation?
|
|
|
|
static let provider = MoyaProvider<SPApi>(requestClosure: CustomApiTimeoutClosure)
|
|
|
|
static func request<T>(parameters: SPNetworkParameters, completion: ((_ response: SPNetworkResponse<T>) -> Void)?) {
|
|
|
|
if SPLoginManager.manager.token == nil {
|
|
self.requestToken(completer: nil)
|
|
}
|
|
|
|
|
|
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
|
|
|
|
let requestOperation = BlockOperation {
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
_request(parameters: parameters) { (response: SPNetworkResponse<T>) in
|
|
semaphore.signal()
|
|
completion?(response)
|
|
}
|
|
semaphore.wait()
|
|
}
|
|
///设置依赖关系
|
|
requestOperation.addDependency(tokenOperation)
|
|
|
|
operationQueue.addOperation(requestOperation)
|
|
} else {
|
|
_request(parameters: parameters, completion: completion)
|
|
}
|
|
}
|
|
|
|
@discardableResult
|
|
static func _request<T>(parameters: SPNetworkParameters, completion: ((_ response: SPNetworkResponse<T>) -> Void)?) -> Cancellable {
|
|
|
|
if parameters.isLoding {
|
|
SPHUD.show()
|
|
}
|
|
return provider.requestCustomJson(.request(parameters: parameters)) { (result) in
|
|
|
|
if parameters.isLoding {
|
|
SPHUD.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 {
|
|
|
|
if parameters.path == "/customer/register" {
|
|
var res = SPNetworkResponse<T>()
|
|
res.code = -1
|
|
if parameters.isToast {
|
|
SPToast.show(text: "movia_error".localized)
|
|
}
|
|
completion?(res)
|
|
} else {
|
|
///重新获取token
|
|
self.requestToken(completer: nil)
|
|
|
|
///将请求失败数据重新请求
|
|
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
|
|
|
|
let requestOperation = BlockOperation {
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
_request(parameters: parameters) { (response: SPNetworkResponse<T>) in
|
|
semaphore.signal()
|
|
completion?(response)
|
|
}
|
|
semaphore.wait()
|
|
}
|
|
///设置依赖关系
|
|
requestOperation.addDependency(tokenOperation)
|
|
|
|
operationQueue.addOperation(requestOperation)
|
|
}
|
|
}
|
|
|
|
|
|
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: "movia_error".localized)
|
|
}
|
|
completion?(res)
|
|
}
|
|
case .failure(let error):
|
|
spLog(message: error)
|
|
var res = SPNetworkResponse<T>()
|
|
res.code = -1
|
|
if parameters.isToast {
|
|
SPToast.show(text: "movia_network_toast_01".localized)
|
|
}
|
|
completion?(res)
|
|
break
|
|
}
|
|
|
|
}
|
|
|
|
///解析数据
|
|
static private func _deserialize<T>(data: String) -> SPNetworkResponse<T> {
|
|
var response: SPNetworkResponse<T>?
|
|
|
|
let time = Date().timeIntervalSince1970
|
|
let decrypted = CryptorService.decrypt(data: 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 = "movia_error".localized
|
|
return response
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extension SPNetwork {
|
|
///获取token
|
|
static func requestToken(completer: ((_ token: SPTokenModel?) -> Void)?) {
|
|
guard self.tokenOperation == nil else {
|
|
completer?(nil)
|
|
return
|
|
}
|
|
|
|
self.tokenOperation = BlockOperation(block: {
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
let param = SPNetworkParameters(path: "/customer/register")
|
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPTokenModel>) in
|
|
if let token = response.data {
|
|
SPLoginManager.manager.setLoginToken(token: token)
|
|
}
|
|
do { semaphore.signal() }
|
|
self.tokenOperation = nil
|
|
completer?(response.data)
|
|
}
|
|
semaphore.wait()
|
|
})
|
|
operationQueue.addOperation(self.tokenOperation!)
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
}
|