@@ -423,12 +423,14 @@ open class ImageDownloader: @unchecked Sendable {
423423
424424 private func startDownloadTask(
425425 context: DownloadingContext ,
426- callback: SessionDataTask . TaskCallback
426+ callback: SessionDataTask . TaskCallback ,
427+ beforeTaskResume: ( ( DownloadTask ) -> Void ) ? = nil
427428 ) -> DownloadTask
428429 {
429430 let downloadTask = addDownloadTask ( context: context, callback: callback)
430431
431432 guard let sessionTask = downloadTask. sessionTask, !sessionTask. started else {
433+ beforeTaskResume ? ( downloadTask)
432434 return downloadTask
433435 }
434436
@@ -468,6 +470,10 @@ open class ImageDownloader: @unchecked Sendable {
468470 }
469471 }
470472
473+ // Ensure `beforeTaskResume` runs before `resume()`. Some stubbing layers may complete the request
474+ // synchronously during `resume()`, so any "task started" callback should be invoked before that.
475+ beforeTaskResume ? ( downloadTask)
476+
471477 reportWillDownloadImage ( url: context. url, request: context. request)
472478 sessionTask. resume ( )
473479 return downloadTask
@@ -493,18 +499,15 @@ open class ImageDownloader: @unchecked Sendable {
493499 createDownloadContext ( with: url, options: options) { result in
494500 switch result {
495501 case . success( let context) :
496- // `downloadTask` will be set if the downloading started immediately. This is the case when no request
497- // modifier or a sync modifier (`ImageDownloadRequestModifier`) is used. Otherwise, when an
498- // `AsyncImageDownloadRequestModifier` is used the returned `downloadTask` of this method will be `nil`
499- // and the actual "delayed" task is given in `AsyncImageDownloadRequestModifier.onDownloadTaskStarted`
500- // callback.
501- let actualDownloadTask = self . startDownloadTask (
502- context: context,
503- callback: self . createTaskCallback ( completionHandler, options: options)
504- )
505- downloadTask. linkToTask ( actualDownloadTask)
502+ let taskCallback = self . createTaskCallback ( completionHandler, options: options)
506503 if let modifier = options. requestModifier {
507- modifier. onDownloadTaskStarted ? ( downloadTask)
504+ _ = self . startDownloadTask ( context: context, callback: taskCallback, beforeTaskResume: { actualDownloadTask in
505+ downloadTask. linkToTask ( actualDownloadTask)
506+ modifier. onDownloadTaskStarted ? ( downloadTask)
507+ } )
508+ } else {
509+ let actualDownloadTask = self . startDownloadTask ( context: context, callback: taskCallback)
510+ downloadTask. linkToTask ( actualDownloadTask)
508511 }
509512 case . failure( let error) :
510513 options. callbackQueue. execute {
0 commit comments