206 lines
7.2 KiB
Swift
206 lines
7.2 KiB
Swift
//
|
|
// NRNetwork.swift
|
|
// ReaderHive
|
|
//
|
|
// Created by 澜声世纪 on 2025/11/21.
|
|
//
|
|
|
|
import UIKit
|
|
import Moya
|
|
import SmartCodable
|
|
|
|
class NRNetwork: NSObject {
|
|
|
|
private static let operationQueue = OperationQueue()
|
|
private static var tokenOperation: BlockOperation?
|
|
|
|
static let provider = MoyaProvider<NRTargetType>()
|
|
|
|
|
|
static func request<T>(parameters: NRNetwork.Parameters, completion: ((_ response: NRNetwork.Response<T>) -> Void)?) {
|
|
|
|
if NRLoginManager.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: NRNetwork.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: NRNetwork.Parameters, completion: ((_ response: NRNetwork.Response<T>) -> Void)?) -> Cancellable {
|
|
|
|
if parameters.isLoding {
|
|
DispatchQueue.main.async {
|
|
NRHud.show()
|
|
}
|
|
}
|
|
return provider.request(.request(parameters: parameters)) { result in
|
|
if parameters.isLoding {
|
|
DispatchQueue.main.async {
|
|
NRHud.dismiss()
|
|
}
|
|
}
|
|
guard let completion = completion else {return}
|
|
_resultDispose(parameters: parameters, result: result, completion: completion)
|
|
}
|
|
}
|
|
|
|
private static func _resultDispose<T>(parameters: NRNetwork.Parameters, result: Result<Moya.Response, MoyaError>, completion: ((_ response: NRNetwork.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 = NRNetwork.Response<T>()
|
|
res.code = -1
|
|
if parameters.isToast {
|
|
DispatchQueue.main.async {
|
|
NRToast.show(text: "Error".localized)
|
|
}
|
|
}
|
|
completion?(res)
|
|
} else {
|
|
if code == 402, parameters.isToast {
|
|
DispatchQueue.main.async {
|
|
NRToast.show(text: "reader_kick_out_login".localized)
|
|
}
|
|
}
|
|
//重新获取token
|
|
self.requestToken { token in
|
|
if token != nil {
|
|
_Concurrency.Task {
|
|
await NRLoginManager.manager.updateUserInfo()
|
|
}
|
|
}
|
|
}
|
|
|
|
///将请求失败数据重新请求
|
|
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
|
|
|
|
let requestOperation = BlockOperation {
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
_request(parameters: parameters) { (response: NRNetwork.Response<T>) in
|
|
semaphore.signal()
|
|
completion?(response)
|
|
}
|
|
semaphore.wait()
|
|
}
|
|
///设置依赖关系
|
|
requestOperation.addDependency(tokenOperation)
|
|
|
|
operationQueue.addOperation(requestOperation)
|
|
}
|
|
}
|
|
|
|
|
|
return
|
|
}
|
|
|
|
do {
|
|
let tempData = try response.mapString()
|
|
nrPrint(message: parameters.parameters)
|
|
nrPrint(message: parameters.path)
|
|
|
|
let response: NRNetwork.Response<T> = _deserialize(data: tempData)
|
|
if !response.isSuccess{
|
|
if parameters.isToast {
|
|
DispatchQueue.main.async {
|
|
NRToast.show(text: response.msg)
|
|
}
|
|
}
|
|
}
|
|
completion?(response)
|
|
|
|
} catch {
|
|
var res = NRNetwork.Response<T>()
|
|
res.code = -1
|
|
if parameters.isToast {
|
|
DispatchQueue.main.async {
|
|
NRToast.show(text: "Error".localized)
|
|
}
|
|
}
|
|
completion?(res)
|
|
}
|
|
case .failure(let error):
|
|
nrPrint(message: error)
|
|
var res = NRNetwork.Response<T>()
|
|
res.code = -1
|
|
if parameters.isToast {
|
|
DispatchQueue.main.async {
|
|
NRToast.show(text: "reader_network_error".localized)
|
|
}
|
|
}
|
|
completion?(res)
|
|
break
|
|
}
|
|
|
|
}
|
|
|
|
///解析数据
|
|
static private func _deserialize<T>(data: String) -> NRNetwork.Response<T> {
|
|
var response: NRNetwork.Response<T>?
|
|
|
|
let decrypted = NRResponseCryptor.decrypt(data: data)
|
|
nrPrint(message: decrypted)
|
|
response = NRNetwork.Response<T>.deserialize(from: decrypted)
|
|
response?.rawData = decrypted
|
|
|
|
if let response = response {
|
|
return response
|
|
} else {
|
|
var response = NRNetwork.Response<T>()
|
|
response.code = -1
|
|
response.msg = "Error".localized
|
|
return response
|
|
}
|
|
}
|
|
}
|
|
|
|
extension NRNetwork {
|
|
|
|
///获取token
|
|
static func requestToken(completer: ((_ token: NRLoginToken?) -> Void)?) {
|
|
guard self.tokenOperation == nil else {
|
|
completer?(nil)
|
|
return
|
|
}
|
|
|
|
self.tokenOperation = BlockOperation(block: {
|
|
let semaphore = DispatchSemaphore(value: 0)
|
|
let param = NRNetwork.Parameters(path: "/customer/register")
|
|
|
|
DispatchQueue.main.async {
|
|
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRLoginToken>) in
|
|
if let token = response.data {
|
|
NRLoginManager.manager.setAccountToken(token)
|
|
}
|
|
do { semaphore.signal() }
|
|
self.tokenOperation = nil
|
|
completer?(response.data)
|
|
}
|
|
}
|
|
semaphore.wait()
|
|
})
|
|
operationQueue.addOperation(self.tokenOperation!)
|
|
}
|
|
}
|