服务商获取权限失败的话retry,更换了首页的背景图

This commit is contained in:
DDIsFriend
2023-11-21 13:47:33 +08:00
parent cfd5d93c71
commit 11d838906f
28 changed files with 921 additions and 372 deletions

View File

@@ -125,11 +125,10 @@ public class Request {
}
/// Protected `MutableState` value that provides thread-safe access to state values.
@Protected
fileprivate var mutableState = MutableState()
fileprivate let mutableState = Protected(MutableState())
/// `State` of the `Request`.
public var state: State { $mutableState.state }
public var state: State { mutableState.state }
/// Returns whether `state` is `.initialized`.
public var isInitialized: Bool { state == .initialized }
/// Returns whether `state is `.resumed`.
@@ -152,50 +151,49 @@ public class Request {
public let downloadProgress = Progress(totalUnitCount: 0)
/// `ProgressHandler` called when `uploadProgress` is updated, on the provided `DispatchQueue`.
private var uploadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? {
get { $mutableState.uploadProgressHandler }
set { $mutableState.uploadProgressHandler = newValue }
get { mutableState.uploadProgressHandler }
set { mutableState.uploadProgressHandler = newValue }
}
/// `ProgressHandler` called when `downloadProgress` is updated, on the provided `DispatchQueue`.
fileprivate var downloadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? {
get { $mutableState.downloadProgressHandler }
set { $mutableState.downloadProgressHandler = newValue }
get { mutableState.downloadProgressHandler }
set { mutableState.downloadProgressHandler = newValue }
}
// MARK: Redirect Handling
/// `RedirectHandler` set on the instance.
public private(set) var redirectHandler: RedirectHandler? {
get { $mutableState.redirectHandler }
set { $mutableState.redirectHandler = newValue }
get { mutableState.redirectHandler }
set { mutableState.redirectHandler = newValue }
}
// MARK: Cached Response Handling
/// `CachedResponseHandler` set on the instance.
public private(set) var cachedResponseHandler: CachedResponseHandler? {
get { $mutableState.cachedResponseHandler }
set { $mutableState.cachedResponseHandler = newValue }
get { mutableState.cachedResponseHandler }
set { mutableState.cachedResponseHandler = newValue }
}
// MARK: URLCredential
/// `URLCredential` used for authentication challenges. Created by calling one of the `authenticate` methods.
public private(set) var credential: URLCredential? {
get { $mutableState.credential }
set { $mutableState.credential = newValue }
get { mutableState.credential }
set { mutableState.credential = newValue }
}
// MARK: Validators
/// `Validator` callback closures that store the validation calls enqueued.
@Protected
fileprivate var validators: [() -> Void] = []
fileprivate let validators = Protected<[() -> Void]>([])
// MARK: URLRequests
/// All `URLRequests` created on behalf of the `Request`, including original and adapted requests.
public var requests: [URLRequest] { $mutableState.requests }
public var requests: [URLRequest] { mutableState.requests }
/// First `URLRequest` created on behalf of the `Request`. May not be the first one actually executed.
public var firstRequest: URLRequest? { requests.first }
/// Last `URLRequest` created on behalf of the `Request`.
@@ -205,7 +203,7 @@ public class Request {
/// `URLRequest`s from all of the `URLSessionTask`s executed on behalf of the `Request`. May be different from
/// `requests` due to `URLSession` manipulation.
public var performedRequests: [URLRequest] { $mutableState.read { $0.tasks.compactMap(\.currentRequest) } }
public var performedRequests: [URLRequest] { mutableState.read { $0.tasks.compactMap(\.currentRequest) } }
// MARK: HTTPURLResponse
@@ -216,7 +214,7 @@ public class Request {
// MARK: Tasks
/// All `URLSessionTask`s created on behalf of the `Request`.
public var tasks: [URLSessionTask] { $mutableState.tasks }
public var tasks: [URLSessionTask] { mutableState.tasks }
/// First `URLSessionTask` created on behalf of the `Request`.
public var firstTask: URLSessionTask? { tasks.first }
/// Last `URLSessionTask` created on behalf of the `Request`.
@@ -227,7 +225,7 @@ public class Request {
// MARK: Metrics
/// All `URLSessionTaskMetrics` gathered on behalf of the `Request`. Should correspond to the `tasks` created.
public var allMetrics: [URLSessionTaskMetrics] { $mutableState.metrics }
public var allMetrics: [URLSessionTaskMetrics] { mutableState.metrics }
/// First `URLSessionTaskMetrics` gathered on behalf of the `Request`.
public var firstMetrics: URLSessionTaskMetrics? { allMetrics.first }
/// Last `URLSessionTaskMetrics` gathered on behalf of the `Request`.
@@ -238,14 +236,14 @@ public class Request {
// MARK: Retry Count
/// Number of times the `Request` has been retried.
public var retryCount: Int { $mutableState.retryCount }
public var retryCount: Int { mutableState.retryCount }
// MARK: Error
/// `Error` returned from Alamofire internally, from the network request directly, or any validators executed.
public fileprivate(set) var error: AFError? {
get { $mutableState.error }
set { $mutableState.error = newValue }
get { mutableState.error }
set { mutableState.error = newValue }
}
/// Default initializer for the `Request` superclass.
@@ -283,7 +281,7 @@ public class Request {
func didCreateInitialURLRequest(_ request: URLRequest) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.write { $0.requests.append(request) }
mutableState.write { $0.requests.append(request) }
eventMonitor?.request(self, didCreateInitialURLRequest: request)
}
@@ -313,7 +311,7 @@ public class Request {
func didAdaptInitialRequest(_ initialRequest: URLRequest, to adaptedRequest: URLRequest) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.write { $0.requests.append(adaptedRequest) }
mutableState.write { $0.requests.append(adaptedRequest) }
eventMonitor?.request(self, didAdaptInitialRequest: initialRequest, to: adaptedRequest)
}
@@ -343,7 +341,7 @@ public class Request {
func didCreateURLRequest(_ request: URLRequest) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.read { state in
mutableState.read { state in
state.urlRequestHandler?.queue.async { state.urlRequestHandler?.handler(request) }
}
@@ -354,7 +352,7 @@ public class Request {
/// Asynchronously calls any stored `cURLHandler` and then removes it from `mutableState`.
private func callCURLHandlerIfNecessary() {
$mutableState.write { mutableState in
mutableState.write { mutableState in
guard let cURLHandler = mutableState.cURLHandler else { return }
cURLHandler.queue.async { cURLHandler.handler(self.cURLDescription()) }
@@ -369,7 +367,7 @@ public class Request {
func didCreateTask(_ task: URLSessionTask) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.write { state in
mutableState.write { state in
state.tasks.append(task)
guard let urlSessionTaskHandler = state.urlSessionTaskHandler else { return }
@@ -416,7 +414,9 @@ public class Request {
func didCancel() {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
error = error ?? AFError.explicitlyCancelled
mutableState.write { mutableState in
mutableState.error = mutableState.error ?? AFError.explicitlyCancelled
}
eventMonitor?.requestDidCancel(self)
}
@@ -436,7 +436,7 @@ public class Request {
func didGatherMetrics(_ metrics: URLSessionTaskMetrics) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.write { $0.metrics.append(metrics) }
mutableState.write { $0.metrics.append(metrics) }
eventMonitor?.request(self, didGatherMetrics: metrics)
}
@@ -468,6 +468,7 @@ public class Request {
self.error = self.error ?? error
let validators = validators.read { $0 }
validators.forEach { $0() }
eventMonitor?.request(self, didCompleteTask: task, with: error)
@@ -479,7 +480,7 @@ public class Request {
func prepareForRetry() {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
$mutableState.write { $0.retryCount += 1 }
mutableState.write { $0.retryCount += 1 }
reset()
@@ -513,9 +514,9 @@ public class Request {
func finish(error: AFError? = nil) {
dispatchPrecondition(condition: .onQueue(underlyingQueue))
guard !$mutableState.isFinishing else { return }
guard !mutableState.isFinishing else { return }
$mutableState.isFinishing = true
mutableState.isFinishing = true
if let error = error { self.error = error }
@@ -531,7 +532,7 @@ public class Request {
///
/// - Parameter closure: The closure containing the response serialization call.
func appendResponseSerializer(_ closure: @escaping () -> Void) {
$mutableState.write { mutableState in
mutableState.write { mutableState in
mutableState.responseSerializers.append(closure)
if mutableState.state == .finished {
@@ -554,7 +555,7 @@ public class Request {
func nextResponseSerializer() -> (() -> Void)? {
var responseSerializer: (() -> Void)?
$mutableState.write { mutableState in
mutableState.write { mutableState in
let responseSerializerIndex = mutableState.responseSerializerCompletions.count
if responseSerializerIndex < mutableState.responseSerializers.count {
@@ -571,7 +572,7 @@ public class Request {
// Execute all response serializer completions and clear them
var completions: [() -> Void] = []
$mutableState.write { mutableState in
mutableState.write { mutableState in
completions = mutableState.responseSerializerCompletions
// Clear out all response serializers and response serializer completions in mutable state since the
@@ -605,7 +606,7 @@ public class Request {
/// - Parameter completion: The completion handler provided with the response serializer, called when all serializers
/// are complete.
func responseSerializerDidComplete(completion: @escaping () -> Void) {
$mutableState.write { $0.responseSerializerCompletions.append(completion) }
mutableState.write { $0.responseSerializerCompletions.append(completion) }
processNextResponseSerializer()
}
@@ -618,7 +619,7 @@ public class Request {
downloadProgress.totalUnitCount = 0
downloadProgress.completedUnitCount = 0
$mutableState.write { state in
mutableState.write { state in
state.isFinishing = false
state.responseSerializerCompletions = []
}
@@ -640,7 +641,7 @@ public class Request {
///
/// - Parameter perform: The closure to perform.
func withState(perform: (State) -> Void) {
$mutableState.withState(perform: perform)
mutableState.withState(perform: perform)
}
// MARK: Task Creation
@@ -667,7 +668,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func cancel() -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
guard mutableState.state.canTransitionTo(.cancelled) else { return }
mutableState.state = .cancelled
@@ -693,7 +694,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func suspend() -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
guard mutableState.state.canTransitionTo(.suspended) else { return }
mutableState.state = .suspended
@@ -714,7 +715,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func resume() -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
guard mutableState.state.canTransitionTo(.resumed) else { return }
mutableState.state = .resumed
@@ -754,7 +755,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func authenticate(with credential: URLCredential) -> Self {
$mutableState.credential = credential
mutableState.credential = credential
return self
}
@@ -770,7 +771,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func downloadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self {
$mutableState.downloadProgressHandler = (handler: closure, queue: queue)
mutableState.downloadProgressHandler = (handler: closure, queue: queue)
return self
}
@@ -786,7 +787,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func uploadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self {
$mutableState.uploadProgressHandler = (handler: closure, queue: queue)
mutableState.uploadProgressHandler = (handler: closure, queue: queue)
return self
}
@@ -802,7 +803,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func redirect(using handler: RedirectHandler) -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
precondition(mutableState.redirectHandler == nil, "Redirect handler has already been set.")
mutableState.redirectHandler = handler
}
@@ -821,7 +822,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func cacheResponse(using handler: CachedResponseHandler) -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
precondition(mutableState.cachedResponseHandler == nil, "Cached response handler has already been set.")
mutableState.cachedResponseHandler = handler
}
@@ -842,7 +843,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func cURLDescription(on queue: DispatchQueue, calling handler: @escaping (String) -> Void) -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
if mutableState.requests.last != nil {
queue.async { handler(self.cURLDescription()) }
} else {
@@ -863,13 +864,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func cURLDescription(calling handler: @escaping (String) -> Void) -> Self {
$mutableState.write { mutableState in
if mutableState.requests.last != nil {
underlyingQueue.async { handler(self.cURLDescription()) }
} else {
mutableState.cURLHandler = (underlyingQueue, handler)
}
}
cURLDescription(on: underlyingQueue, calling: handler)
return self
}
@@ -885,7 +880,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func onURLRequestCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLRequest) -> Void) -> Self {
$mutableState.write { state in
mutableState.write { state in
if let request = state.requests.last {
queue.async { handler(request) }
}
@@ -909,7 +904,7 @@ public class Request {
/// - Returns: The instance.
@discardableResult
public func onURLSessionTaskCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLSessionTask) -> Void) -> Self {
$mutableState.write { state in
mutableState.write { state in
if let task = state.tasks.last {
queue.async { handler(task) }
}
@@ -928,19 +923,37 @@ public class Request {
func onFinish(perform finishHandler: @escaping () -> Void) {
guard !isFinished else { finishHandler(); return }
$mutableState.write { state in
mutableState.write { state in
state.finishHandlers.append(finishHandler)
}
}
/// Final cleanup step executed when the instance finishes response serialization.
func cleanup() {
delegate?.cleanup(after: self)
let handlers = $mutableState.finishHandlers
let handlers = mutableState.finishHandlers
handlers.forEach { $0() }
$mutableState.write { state in
mutableState.write { state in
state.finishHandlers.removeAll()
}
delegate?.cleanup(after: self)
}
}
extension Request {
/// Type indicating how a `DataRequest` or `DataStreamRequest` should proceed after receiving an `HTTPURLResponse`.
public enum ResponseDisposition {
/// Allow the request to continue normally.
case allow
/// Cancel the request, similar to calling `cancel()`.
case cancel
var sessionDisposition: URLSession.ResponseDisposition {
switch self {
case .allow: return .allow
case .cancel: return .cancel
}
}
}
}
@@ -1085,11 +1098,16 @@ public class DataRequest: Request {
/// `URLRequestConvertible` value used to create `URLRequest`s for this instance.
public let convertible: URLRequestConvertible
/// `Data` read from the server so far.
public var data: Data? { mutableData }
public var data: Data? { dataMutableState.data }
/// Protected storage for the `Data` read by the instance.
@Protected
private var mutableData: Data? = nil
private struct DataMutableState {
var data: Data?
var httpResponseHandler: (queue: DispatchQueue,
handler: (_ response: HTTPURLResponse,
_ completionHandler: @escaping (ResponseDisposition) -> Void) -> Void)?
}
private let dataMutableState = Protected(DataMutableState())
/// Creates a `DataRequest` using the provided parameters.
///
@@ -1122,7 +1140,9 @@ public class DataRequest: Request {
override func reset() {
super.reset()
mutableData = nil
dataMutableState.write { mutableState in
mutableState.data = nil
}
}
/// Called when `Data` is received by this instance.
@@ -1131,15 +1151,41 @@ public class DataRequest: Request {
///
/// - Parameter data: The `Data` received.
func didReceive(data: Data) {
if self.data == nil {
mutableData = data
} else {
$mutableData.write { $0?.append(data) }
dataMutableState.write { mutableState in
if mutableState.data == nil {
mutableState.data = data
} else {
mutableState.data?.append(data)
}
}
updateDownloadProgress()
}
func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
dataMutableState.read { dataMutableState in
guard let httpResponseHandler = dataMutableState.httpResponseHandler else {
underlyingQueue.async { completionHandler(.allow) }
return
}
httpResponseHandler.queue.async {
httpResponseHandler.handler(response) { disposition in
if disposition == .cancel {
self.mutableState.write { mutableState in
mutableState.state = .cancelled
mutableState.error = mutableState.error ?? AFError.explicitlyCancelled
}
}
self.underlyingQueue.async {
completionHandler(disposition.sessionDisposition)
}
}
}
}
}
override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask {
let copiedRequest = request
return session.dataTask(with: copiedRequest)
@@ -1179,7 +1225,48 @@ public class DataRequest: Request {
withResult: result)
}
$validators.write { $0.append(validator) }
validators.write { $0.append(validator) }
return self
}
/// Sets a closure called whenever the `DataRequest` produces an `HTTPURLResponse` and providing a completion
/// handler to return a `ResponseDisposition` value.
///
/// - Parameters:
/// - queue: `DispatchQueue` on which the closure will be called. `.main` by default.
/// - handler: Closure called when the instance produces an `HTTPURLResponse`. The `completionHandler` provided
/// MUST be called, otherwise the request will never complete.
///
/// - Returns: The instance.
@_disfavoredOverload
@discardableResult
public func onHTTPResponse(
on queue: DispatchQueue = .main,
perform handler: @escaping (_ response: HTTPURLResponse,
_ completionHandler: @escaping (ResponseDisposition) -> Void) -> Void
) -> Self {
dataMutableState.write { mutableState in
mutableState.httpResponseHandler = (queue, handler)
}
return self
}
/// Sets a closure called whenever the `DataRequest` produces an `HTTPURLResponse`.
///
/// - Parameters:
/// - queue: `DispatchQueue` on which the closure will be called. `.main` by default.
/// - handler: Closure called when the instance produces an `HTTPURLResponse`.
///
/// - Returns: The instance.
@discardableResult
public func onHTTPResponse(on queue: DispatchQueue = .main,
perform handler: @escaping (HTTPURLResponse) -> Void) -> Self {
onHTTPResponse(on: queue) { response, completionHandler in
handler(response)
completionHandler(.allow)
}
return self
}
@@ -1259,10 +1346,13 @@ public final class DataStreamRequest: Request {
var numberOfExecutingStreams = 0
/// Completion calls enqueued while streams are still executing.
var enqueuedCompletionEvents: [() -> Void] = []
/// Handler for any `HTTPURLResponse`s received.
var httpResponseHandler: (queue: DispatchQueue,
handler: (_ response: HTTPURLResponse,
_ completionHandler: @escaping (ResponseDisposition) -> Void) -> Void)?
}
@Protected
var streamMutableState = StreamMutableState()
let streamMutableState = Protected(StreamMutableState())
/// Creates a `DataStreamRequest` using the provided parameters.
///
@@ -1306,7 +1396,7 @@ public final class DataStreamRequest: Request {
}
override func finish(error: AFError? = nil) {
$streamMutableState.write { state in
streamMutableState.write { state in
state.outputStream?.close()
}
@@ -1314,8 +1404,8 @@ public final class DataStreamRequest: Request {
}
func didReceive(data: Data) {
$streamMutableState.write { state in
#if !(os(Linux) || os(Windows))
streamMutableState.write { state in
#if !canImport(FoundationNetworking) // If we not using swift-corelibs-foundation.
if let stream = state.outputStream {
underlyingQueue.async {
var bytes = Array(data)
@@ -1329,6 +1419,30 @@ public final class DataStreamRequest: Request {
}
}
func didReceiveResponse(_ response: HTTPURLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
streamMutableState.read { dataMutableState in
guard let httpResponseHandler = dataMutableState.httpResponseHandler else {
underlyingQueue.async { completionHandler(.allow) }
return
}
httpResponseHandler.queue.async {
httpResponseHandler.handler(response) { disposition in
if disposition == .cancel {
self.mutableState.write { mutableState in
mutableState.state = .cancelled
mutableState.error = mutableState.error ?? AFError.explicitlyCancelled
}
}
self.underlyingQueue.async {
completionHandler(disposition.sessionDisposition)
}
}
}
}
}
/// Validates the `URLRequest` and `HTTPURLResponse` received for the instance using the provided `Validation` closure.
///
/// - Parameter validation: `Validation` closure used to validate the request and response.
@@ -1351,12 +1465,12 @@ public final class DataStreamRequest: Request {
withResult: result)
}
$validators.write { $0.append(validator) }
validators.write { $0.append(validator) }
return self
}
#if !(os(Linux) || os(Windows))
#if !canImport(FoundationNetworking) // If we not using swift-corelibs-foundation.
/// Produces an `InputStream` that receives the `Data` received by the instance.
///
/// - Note: The `InputStream` produced by this method must have `open()` called before being able to read `Data`.
@@ -1370,7 +1484,7 @@ public final class DataStreamRequest: Request {
defer { resume() }
var inputStream: InputStream?
$streamMutableState.write { state in
streamMutableState.write { state in
Foundation.Stream.getBoundStreams(withBufferSize: bufferSize,
inputStream: &inputStream,
outputStream: &state.outputStream)
@@ -1381,6 +1495,47 @@ public final class DataStreamRequest: Request {
}
#endif
/// Sets a closure called whenever the `DataRequest` produces an `HTTPURLResponse` and providing a completion
/// handler to return a `ResponseDisposition` value.
///
/// - Parameters:
/// - queue: `DispatchQueue` on which the closure will be called. `.main` by default.
/// - handler: Closure called when the instance produces an `HTTPURLResponse`. The `completionHandler` provided
/// MUST be called, otherwise the request will never complete.
///
/// - Returns: The instance.
@_disfavoredOverload
@discardableResult
public func onHTTPResponse(
on queue: DispatchQueue = .main,
perform handler: @escaping (_ response: HTTPURLResponse,
_ completionHandler: @escaping (ResponseDisposition) -> Void) -> Void
) -> Self {
streamMutableState.write { mutableState in
mutableState.httpResponseHandler = (queue, handler)
}
return self
}
/// Sets a closure called whenever the `DataRequest` produces an `HTTPURLResponse`.
///
/// - Parameters:
/// - queue: `DispatchQueue` on which the closure will be called. `.main` by default.
/// - handler: Closure called when the instance produces an `HTTPURLResponse`.
///
/// - Returns: The instance.
@discardableResult
public func onHTTPResponse(on queue: DispatchQueue = .main,
perform handler: @escaping (HTTPURLResponse) -> Void) -> Self {
onHTTPResponse(on: queue) { response, completionHandler in
handler(response)
completionHandler(.allow)
}
return self
}
func capturingError(from closure: () throws -> Void) {
do {
try closure()
@@ -1395,7 +1550,7 @@ public final class DataStreamRequest: Request {
appendResponseSerializer {
self.underlyingQueue.async {
self.responseSerializerDidComplete {
self.$streamMutableState.write { state in
self.streamMutableState.write { state in
guard state.numberOfExecutingStreams == 0 else {
state.enqueuedCompletionEvents.append {
self.enqueueCompletion(on: queue, stream: stream)
@@ -1546,23 +1701,22 @@ public class DownloadRequest: Request {
}
/// Protected mutable state specific to `DownloadRequest`.
@Protected
private var mutableDownloadState = DownloadRequestMutableState()
private let mutableDownloadState = Protected(DownloadRequestMutableState())
/// If the download is resumable and is eventually cancelled or fails, this value may be used to resume the download
/// using the `download(resumingWith data:)` API.
///
/// - Note: For more information about `resumeData`, see [Apple's documentation](https://developer.apple.com/documentation/foundation/urlsessiondownloadtask/1411634-cancel).
public var resumeData: Data? {
#if !(os(Linux) || os(Windows))
return $mutableDownloadState.resumeData ?? error?.downloadResumeData
#if !canImport(FoundationNetworking) // If we not using swift-corelibs-foundation.
return mutableDownloadState.resumeData ?? error?.downloadResumeData
#else
return $mutableDownloadState.resumeData
return mutableDownloadState.resumeData
#endif
}
/// If the download is successful, the `URL` where the file was downloaded.
public var fileURL: URL? { $mutableDownloadState.fileURL }
public var fileURL: URL? { mutableDownloadState.fileURL }
// MARK: Initial State
@@ -1605,7 +1759,7 @@ public class DownloadRequest: Request {
override func reset() {
super.reset()
$mutableDownloadState.write {
mutableDownloadState.write {
$0.resumeData = nil
$0.fileURL = nil
}
@@ -1620,7 +1774,7 @@ public class DownloadRequest: Request {
eventMonitor?.request(self, didFinishDownloadingUsing: task, with: result)
switch result {
case let .success(url): $mutableDownloadState.fileURL = url
case let .success(url): mutableDownloadState.fileURL = url
case let .failure(error): self.error = error
}
}
@@ -1698,7 +1852,7 @@ public class DownloadRequest: Request {
///
/// - Returns: The instance.
private func cancel(optionallyProducingResumeData completionHandler: ((_ resumeData: Data?) -> Void)?) -> Self {
$mutableState.write { mutableState in
mutableState.write { mutableState in
guard mutableState.state.canTransitionTo(.cancelled) else { return }
mutableState.state = .cancelled
@@ -1714,7 +1868,7 @@ public class DownloadRequest: Request {
// Resume to ensure metrics are gathered.
task.resume()
task.cancel { resumeData in
self.$mutableDownloadState.resumeData = resumeData
self.mutableDownloadState.resumeData = resumeData
self.underlyingQueue.async { self.didCancelTask(task) }
completionHandler(resumeData)
}
@@ -1754,7 +1908,7 @@ public class DownloadRequest: Request {
withResult: result)
}
$validators.write { $0.append(validator) }
validators.write { $0.append(validator) }
return self
}