@@ -513,6 +513,115 @@ public class AlamofireWrapper: NSObject {
513513 return downloadRequest. task as? URLSessionDownloadTask
514514 }
515515
516+ // MARK: - Early Resolution Support
517+
518+ /**
519+ * Download to temp file with early resolution on headers received.
520+ * Calls headersCallback as soon as headers are available (before download completes).
521+ * Calls completionHandler when download finishes with temp file path.
522+ * This allows inspecting status/headers early and cancelling before full download.
523+ */
524+ @objc public func downloadToTempWithEarlyHeaders(
525+ _ method: String ,
526+ _ urlString: String ,
527+ _ parameters: NSDictionary ? ,
528+ _ headers: NSDictionary ? ,
529+ _ sizeThreshold: Int64 ,
530+ _ progress: ( ( Progress ) -> Void ) ? ,
531+ _ headersCallback: @escaping ( URLResponse ? , Int64 ) -> Void ,
532+ _ completionHandler: @escaping ( URLResponse ? , String ? , Error ? ) -> Void
533+ ) -> URLSessionDownloadTask ? {
534+
535+ guard let url = URL ( string: urlString) else {
536+ let error = NSError ( domain: " AlamofireWrapper " , code: - 1 , userInfo: [ NSLocalizedDescriptionKey: " Invalid URL " ] )
537+ completionHandler ( nil , nil , error)
538+ return nil
539+ }
540+
541+ var request : URLRequest
542+ do {
543+ request = try requestSerializer. createRequest (
544+ url: url,
545+ method: HTTPMethod ( rawValue: method. uppercased ( ) ) ,
546+ parameters: nil ,
547+ headers: headers
548+ )
549+ // Encode parameters into the request
550+ try requestSerializer. encodeParameters ( parameters, into: & request, method: HTTPMethod ( rawValue: method. uppercased ( ) ) )
551+ } catch {
552+ completionHandler ( nil , nil , error)
553+ return nil
554+ }
555+
556+ // Track whether we've already called headersCallback
557+ var headersCallbackCalled = false
558+ let headersCallbackLock = NSLock ( )
559+
560+ // Create destination closure that saves to a temp file
561+ let destination : DownloadRequest . Destination = { temporaryURL, response in
562+ // Create a unique temp file path
563+ let tempDir = FileManager . default. temporaryDirectory
564+ let tempFileName = UUID ( ) . uuidString
565+ let tempFileURL = tempDir. appendingPathComponent ( tempFileName)
566+
567+ // Call headersCallback on first response (only once)
568+ headersCallbackLock. lock ( )
569+ if !headersCallbackCalled {
570+ headersCallbackCalled = true
571+ headersCallbackLock. unlock ( )
572+
573+ let contentLength = response. expectedContentLength
574+ headersCallback ( response, contentLength)
575+ } else {
576+ headersCallbackLock. unlock ( )
577+ }
578+
579+ return ( tempFileURL, [ . removePreviousFile, . createIntermediateDirectories] )
580+ }
581+
582+ var downloadRequest = session. download ( request, to: destination)
583+
584+ // Apply server trust evaluation if security policy is set
585+ if let secPolicy = securityPolicy, let host = url. host {
586+ downloadRequest = downloadRequest. validate { _, response, _ in
587+ guard let serverTrust = response. serverTrust else {
588+ return . failure( AFError . serverTrustEvaluationFailed ( reason: . noServerTrust) )
589+ }
590+ do {
591+ try secPolicy. evaluate ( serverTrust, forHost: host)
592+ return . success( Void ( ) )
593+ } catch {
594+ return . failure( error)
595+ }
596+ }
597+ }
598+
599+ // Download progress
600+ if let progress = progress {
601+ downloadRequest = downloadRequest. downloadProgress { progressInfo in
602+ progress ( progressInfo)
603+ }
604+ }
605+
606+ // Response handling (fires when download completes)
607+ downloadRequest. response ( queue: . main) { response in
608+ if let error = response. error {
609+ completionHandler ( response. response, nil , error)
610+ return
611+ }
612+
613+ // Return the temp file path on success
614+ if let tempFileURL = response. fileURL {
615+ completionHandler ( response. response, tempFileURL. path, nil )
616+ } else {
617+ let error = NSError ( domain: " AlamofireWrapper " , code: - 1 , userInfo: [ NSLocalizedDescriptionKey: " No file URL in download response " ] )
618+ completionHandler ( response. response, nil , error)
619+ }
620+ }
621+
622+ return downloadRequest. task as? URLSessionDownloadTask
623+ }
624+
516625 // MARK: - Helper Methods
517626
518627 private func createNSError( from error: Error , response: HTTPURLResponse ? , data: Data ? ) -> NSError {
0 commit comments