140 lines
4.3 KiB
Swift
140 lines
4.3 KiB
Swift
//
|
||
// NewworkRequest.swift
|
||
// yinmeng-ios
|
||
//
|
||
// Created by MaiMang on 2024/2/2.
|
||
//
|
||
|
||
import Foundation
|
||
import Alamofire
|
||
import Moya
|
||
|
||
public extension YMNetworkAPI {
|
||
@discardableResult func HTTPRequest(
|
||
success: @escaping APISuccess,
|
||
failure: @escaping APIFailure,
|
||
progress: ProgressBlock? = nil,
|
||
queue: DispatchQueue? = nil,
|
||
plugins: APIPlugins = []
|
||
) -> Cancellable? {
|
||
let key = self.keyPrefix
|
||
let plugins__ = YMRequestX.setupPluginsAndKey(key, plugins: self.plugins + plugins)
|
||
|
||
SharedDriver.shared.addedRequestingAPI(self, key: key, plugins: plugins__)
|
||
|
||
let request = self.setupConfiguration(plugins: plugins__)
|
||
if request.endRequest, let result = request.result {
|
||
let lastResult = LastNeverResult(result: result, plugins: plugins__)
|
||
lastResult.mapResult(success: { json in
|
||
SharedDriver.shared.removeRequestingAPI(key)
|
||
DispatchQueue.main.async { success(json) }
|
||
}, failure: { error in
|
||
SharedDriver.shared.removeRequestingAPI(key)
|
||
DispatchQueue.main.async { failure(error) }
|
||
}, progress: progress)
|
||
return nil
|
||
}
|
||
|
||
let session = request.session ?? {
|
||
let configuration = URLSessionConfiguration.af.default
|
||
configuration.timeoutIntervalForRequest = YMRequestConfig.timeoutIntervalForRequest
|
||
return Moya.Session(
|
||
configuration: configuration,
|
||
startRequestsImmediately: false,
|
||
interceptor: YMRequestConfig.interceptor
|
||
)
|
||
}()
|
||
|
||
let queue = queue ?? {
|
||
DispatchQueue(label: "condy.request.network.queue", attributes: [.concurrent])
|
||
}()
|
||
|
||
let target = MultiTarget.target(self)
|
||
let endpointTask = self.task
|
||
var endpointHeaders = YMRequestX.hasNetworkHttpHeaderPlugin(key) ?? YMRequestConfig.baseHeaders
|
||
if let dict = self.headers {
|
||
// Merge the dictionaries and take the second value.
|
||
endpointHeaders = endpointHeaders.merging(dict) { $1 }
|
||
}
|
||
let provider = MoyaProvider<MultiTarget>.init(endpointClosure: { _ in
|
||
Endpoint(url: URL(target: target).absoluteString,
|
||
sampleResponseClosure: { .networkResponse(200, self.sampleData) },
|
||
method: self.method,
|
||
task: endpointTask,
|
||
httpHeaderFields: endpointHeaders)
|
||
}, stubClosure: { _ in
|
||
stubBehavior
|
||
}, callbackQueue: queue, session: session, plugins: plugins__)
|
||
|
||
// 先抛出本地数据
|
||
if let json = try? request.toJSON() {
|
||
DispatchQueue.main.async { success(json) }
|
||
}
|
||
|
||
// 再处理网络数据
|
||
return self.request(plugins__, provider: provider, success: { json in
|
||
SharedDriver.shared.removeRequestingAPI(key)
|
||
DispatchQueue.main.async { success(json) }
|
||
}, failure: { error in
|
||
SharedDriver.shared.removeRequestingAPI(key)
|
||
DispatchQueue.main.async { failure(error) }
|
||
}, progress: progress)
|
||
}
|
||
|
||
@discardableResult
|
||
func request(plugins: APIPlugins = [], complete: @escaping APIComplete) -> Cancellable? {
|
||
HTTPRequest(success: { json in
|
||
complete(.success(json))
|
||
}, failure: { error in
|
||
complete(.failure(error))
|
||
}, plugins: plugins)
|
||
}
|
||
}
|
||
|
||
|
||
extension YMNetworkAPI {
|
||
/// 最开始配置插件信息
|
||
private func setupConfiguration(plugins: APIPlugins) -> HeadstreamRequest {
|
||
var request = HeadstreamRequest()
|
||
plugins.forEach {
|
||
request = $0.configuration(request, target: self)
|
||
}
|
||
return request
|
||
}
|
||
|
||
/// 最后的输出结果,插件配置处理
|
||
private func setupOutputResult(plugins: APIPlugins, result: APIResponseResult, onNext: @escaping LastNeverCallback) {
|
||
var lastResult = LastNeverResult(result: result, plugins: plugins)
|
||
var iterator = plugins.makeIterator()
|
||
func handleLastNever(_ plugin: PluginSubType?) {
|
||
guard let plugin = plugin else {
|
||
onNext(lastResult)
|
||
return
|
||
}
|
||
plugin.lastNever(lastResult, target: self) {
|
||
lastResult = $0
|
||
handleLastNever(iterator.next())
|
||
}
|
||
}
|
||
handleLastNever(iterator.next())
|
||
}
|
||
|
||
private func request(_ plugins: APIPlugins,
|
||
provider: MoyaProvider<MultiTarget>,
|
||
success: @escaping APISuccess,
|
||
failure: @escaping APIFailure,
|
||
progress: ProgressBlock? = nil) -> Cancellable {
|
||
let target = MultiTarget.target(self)
|
||
return provider.request(target, progress: progress, completion: { result in
|
||
setupOutputResult(plugins: plugins, result: result) { lastResult in
|
||
if lastResult.againRequest {
|
||
_ = request(plugins, provider: provider, success: success, failure: failure, progress: progress)
|
||
return
|
||
}
|
||
lastResult.mapResult(success: success, failure: failure)
|
||
}
|
||
})
|
||
}
|
||
|
||
}
|