Skip to content

Commit 54c5c2c

Browse files
committed
fix runtime support for parameterized protocol types is only available in macOS 13.0.0 or newer
1 parent 76f59c4 commit 54c5c2c

1 file changed

Lines changed: 48 additions & 1 deletion

File tree

Source/SmartRequest.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,28 +202,75 @@ private final class SessionAdaptor {
202202
let (asyncBytes, response) = try await session.task(for: request)
203203
task = asyncBytes.task
204204

205+
// Get expected content length from response for accurate progress tracking
206+
let expectedContentLength = response.expectedContentLength
207+
208+
// Also observe task.progress as a fallback, but we'll primarily use manual tracking
209+
// for more accurate and frequent updates
205210
if let progressHandler,
206211
let task {
207212
observer = task.progress.observe(progressHandler)
208213
}
209214

210215
var data = Data()
216+
var bytesRead: Int64 = 0
217+
// Update progress every 1KB or when significant chunk is received
218+
// This provides smoother progress updates than relying solely on task.progress
219+
let progressUpdateThreshold: Int64 = 1024
211220

212221
for try await byte in asyncBytes {
213222
try Task.checkCancellation()
214223
data.append(byte)
224+
bytesRead += 1
225+
226+
// Manually update progress if expectedContentLength is known
227+
// This ensures we get regular updates even if task.progress updates infrequently
228+
if let progressHandler = progressHandler,
229+
expectedContentLength > 0,
230+
bytesRead % progressUpdateThreshold == 0 {
231+
let progress = Progress(totalUnitCount: expectedContentLength)
232+
progress.completedUnitCount = bytesRead
233+
progressHandler(progress)
234+
} else if let progressHandler = progressHandler,
235+
expectedContentLength < 0,
236+
bytesRead % progressUpdateThreshold == 0 {
237+
// If content length is unknown, create indeterminate progress
238+
// that shows we're making progress (bytesRead increases)
239+
let progress = Progress(totalUnitCount: -1)
240+
progress.completedUnitCount = bytesRead
241+
progressHandler(progress)
242+
}
243+
}
244+
245+
// Send final progress update (100%) if we have a handler and expected length
246+
// This ensures completion is always reported, even if task.progress didn't update
247+
if let progressHandler = progressHandler {
248+
if expectedContentLength > 0 {
249+
let progress = Progress(totalUnitCount: expectedContentLength)
250+
progress.completedUnitCount = expectedContentLength
251+
progressHandler(progress)
252+
} else {
253+
// For unknown length, send completion with bytesRead as total
254+
let progress = Progress(totalUnitCount: bytesRead)
255+
progress.completedUnitCount = bytesRead
256+
progressHandler(progress)
257+
}
215258
}
216259

217260
return (data, response)
218261
}
219262

220263
/// Cancels the running task and clears its observer.
221264
func stop() {
265+
// Clear observer first to prevent any further progress updates
266+
observer = nil
267+
268+
// Then cancel the task if it's running
222269
if task?.state == .running {
223270
task?.cancel()
224271
}
272+
225273
task = nil
226-
observer = nil
227274
}
228275
}
229276

0 commit comments

Comments
 (0)