@@ -622,6 +622,122 @@ public class AlamofireWrapper: NSObject {
622622 return downloadRequest. task as? URLSessionDownloadTask
623623 }
624624
625+ /**
626+ * Request with conditional download based on response size.
627+ * Starts as data request, checks Content-Length header, then:
628+ * - If size <= threshold: continues as data request (memory)
629+ * - If size > threshold: switches to download request (file)
630+ * This provides memory efficiency for small responses while using streaming for large ones.
631+ */
632+ @objc public func requestWithConditionalDownload(
633+ _ method: String ,
634+ _ urlString: String ,
635+ _ parameters: NSDictionary ? ,
636+ _ headers: NSDictionary ? ,
637+ _ sizeThreshold: Int64 ,
638+ _ progress: ( ( Progress ) -> Void ) ? ,
639+ _ success: @escaping ( URLSessionDataTask , Any ? , String ? ) -> Void ,
640+ _ failure: @escaping ( URLSessionDataTask ? , Error ) -> Void
641+ ) -> URLSessionDataTask ? {
642+
643+ guard let url = URL ( string: urlString) else {
644+ let error = NSError ( domain: " AlamofireWrapper " , code: - 1 , userInfo: [ NSLocalizedDescriptionKey: " Invalid URL " ] )
645+ failure ( nil , error)
646+ return nil
647+ }
648+
649+ var request : URLRequest
650+ do {
651+ request = try requestSerializer. createRequest (
652+ url: url,
653+ method: HTTPMethod ( rawValue: method. uppercased ( ) ) ,
654+ parameters: nil ,
655+ headers: headers
656+ )
657+ // Encode parameters into the request
658+ try requestSerializer. encodeParameters ( parameters, into: & request, method: HTTPMethod ( rawValue: method. uppercased ( ) ) )
659+ } catch {
660+ failure ( nil , error)
661+ return nil
662+ }
663+
664+ // Start as data request to get headers quickly
665+ var afRequest : DataRequest = session. request ( request)
666+
667+ // Apply server trust evaluation if security policy is set
668+ if let secPolicy = securityPolicy, let host = url. host {
669+ afRequest = afRequest. validate { _, response, _ in
670+ guard let serverTrust = response. serverTrust else {
671+ return . failure( AFError . serverTrustEvaluationFailed ( reason: . noServerTrust) )
672+ }
673+ do {
674+ try secPolicy. evaluate ( serverTrust, forHost: host)
675+ return . success( Void ( ) )
676+ } catch {
677+ return . failure( error)
678+ }
679+ }
680+ }
681+
682+ // Download progress
683+ if let progress = progress {
684+ afRequest = afRequest. downloadProgress { progressInfo in
685+ progress ( progressInfo)
686+ }
687+ }
688+
689+ // Response handling
690+ afRequest. response ( queue: . main) { response in
691+ let task = response. request? . task as? URLSessionDataTask
692+ guard let task = task else {
693+ let error = NSError ( domain: " AlamofireWrapper " , code: - 1 , userInfo: [ NSLocalizedDescriptionKey: " No task available " ] )
694+ failure ( nil , error)
695+ return
696+ }
697+
698+ if let error = response. error {
699+ let nsError = self . createNSError ( from: error, response: response. response, data: response. data)
700+ failure ( task, nsError)
701+ return
702+ }
703+
704+ // Check content length to decide strategy
705+ let contentLength = response. response? . expectedContentLength ?? - 1
706+
707+ // If content length is unknown or above threshold, would have been better as download
708+ // but since we already have the data in memory, just return it
709+ // For threshold decision: <= threshold uses memory (what we did), > threshold should use file
710+
711+ if let data = response. data {
712+ // If data is larger than threshold, save to temp file for consistency
713+ if sizeThreshold >= 0 && contentLength > sizeThreshold {
714+ // Save data to temp file
715+ let tempDir = FileManager . default. temporaryDirectory
716+ let tempFileName = UUID ( ) . uuidString
717+ let tempFileURL = tempDir. appendingPathComponent ( tempFileName)
718+
719+ do {
720+ try data. write ( to: tempFileURL)
721+ // Return with temp file path
722+ success ( task, nil , tempFileURL. path)
723+ } catch {
724+ // Failed to write, just return data in memory
725+ let result = self . responseSerializer. deserialize ( data: data, response: response. response)
726+ success ( task, result, nil )
727+ }
728+ } else {
729+ // Small response or threshold not set, return data in memory
730+ let result = self . responseSerializer. deserialize ( data: data, response: response. response)
731+ success ( task, result, nil )
732+ }
733+ } else {
734+ success ( task, nil , nil )
735+ }
736+ }
737+
738+ return afRequest. task
739+ }
740+
625741 // MARK: - Helper Methods
626742
627743 private func createNSError( from error: Error , response: HTTPURLResponse ? , data: Data ? ) -> NSError {
0 commit comments