2025-11-20 16:59:32 +08:00

194 lines
6.7 KiB
Swift

//
// SRNetwork.swift
// SynthReel
//
// Created by on 2025/11/12.
// Copyright © 2025 SR. All rights reserved.
//
import UIKit
import Moya
import SmartCodable
class SRNetwork: NSObject {
private static let operationQueue = OperationQueue()
private static var tokenOperation: BlockOperation?
static let provider = MoyaProvider<SRTargetType>()
static func request<T>(parameters: SRNetwork.Parameters, completion: ((_ response: SRNetwork.Response<T>) -> Void)?) {
if SRAccountManager.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: SRNetwork.Response<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: SRNetwork.Parameters, completion: ((_ response: SRNetwork.Response<T>) -> Void)?) -> Cancellable {
if parameters.isLoding {
SRHud.show()
}
return provider.request(.request(parameters: parameters)) { result in
if parameters.isLoding {
SRHud.dismiss()
}
guard let completion = completion else {return}
_resultDispose(parameters: parameters, result: result, completion: completion)
}
}
private static func _resultDispose<T>(parameters: SRNetwork.Parameters, result: Result<Moya.Response, MoyaError>, completion: ((_ response: SRNetwork.Response<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 = SRNetwork.Response<T>()
res.code = -1
if parameters.isToast {
// BRToast.show(text: "Error".localized)
}
completion?(res)
} else {
// if code == 402, parameters.isToast {
// BRToast.show(text: "beereel_network_error_1".localized)
// }
///token
self.requestToken { token in
if token != nil {
_Concurrency.Task {
await SRAccountManager.manager.updateUserInfo()
}
}
}
///
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
let requestOperation = BlockOperation {
let semaphore = DispatchSemaphore(value: 0)
_request(parameters: parameters) { (response: SRNetwork.Response<T>) in
semaphore.signal()
completion?(response)
}
semaphore.wait()
}
///
requestOperation.addDependency(tokenOperation)
operationQueue.addOperation(requestOperation)
}
}
return
}
do {
let tempData = try response.mapString()
srPrint(message: parameters.parameters)
srPrint(message: parameters.path)
let response: SRNetwork.Response<T> = _deserialize(data: tempData)
if !response.isSuccess{
if parameters.isToast {
// BRToast.show(text: response.msg)
}
}
completion?(response)
} catch {
var res = SRNetwork.Response<T>()
res.code = -1
if parameters.isToast {
// BRToast.show(text: "Error".localized)
}
completion?(res)
}
case .failure(let error):
srPrint(message: error)
var res = SRNetwork.Response<T>()
res.code = -1
if parameters.isToast {
// BRToast.show(text: "beereel_network".localized)
}
completion?(res)
break
}
}
///
static private func _deserialize<T>(data: String) -> SRNetwork.Response<T> {
var response: SRNetwork.Response<T>?
let decrypted = SRResponseCryptor.decrypt(data: data)
srPrint(message: decrypted)
response = SRNetwork.Response<T>.deserialize(from: decrypted)
response?.rawData = decrypted
if let response = response {
return response
} else {
var response = SRNetwork.Response<T>()
response.code = -1
response.msg = "Error".localized
return response
}
}
}
extension SRNetwork {
///token
static func requestToken(completer: ((_ token: SRAccountToken?) -> Void)?) {
guard self.tokenOperation == nil else {
completer?(nil)
return
}
self.tokenOperation = BlockOperation(block: {
let semaphore = DispatchSemaphore(value: 0)
let param = SRNetwork.Parameters(path: "/customer/register")
DispatchQueue.main.async {
SRNetwork.request(parameters: param) { (response: SRNetwork.Response<SRAccountToken>) in
if let token = response.data {
SRAccountManager.manager.setAccountToken(token)
}
do { semaphore.signal() }
self.tokenOperation = nil
completer?(response.data)
}
}
semaphore.wait()
})
operationQueue.addOperation(self.tokenOperation!)
}
}