Files
yingmeng-ios-switf/yinmeng-ios/HttpRequest/NetworkRequest.swift
2024-02-21 21:30:13 +08:00

140 lines
4.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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)
}
})
}
}