Skip to content

[Feature]: Upload progress callbacks for Storage uploads (Swift parity with Android SDK) #957

@arbyruns

Description

@arbyruns

Searched existing issues?

  • I have searched the existing issues

Problem Description

The Android SDK supports upload progress tracking via uploadAsFlow, which emits UploadStatus.Progress events during an upload:

val bucket = supabase.storage.from("avatars")
bucket.uploadAsFlow("test.png", byteArrayOf()).collect {
    when(it) {
        is UploadStatus.Progress -> println("Progress: ${it.totalBytesSend.toFloat() / it.contentLength * 100}%")
        is UploadStatus.Success -> println("Success")
    }
}

The Swift SDK has no equivalent. The current API is fire-and-forget with no way to observe bytes sent:

try await supabase.storage
    .from("avatars")
    .upload(
        path: "public/avatar.png",
        file: fileData,
        options: FileOptions(contentType: "image/png")
    )

Proposed Solution

Proposed Swift API — an AsyncSequence-based equivalent that fits naturally into Swift concurrency.

for try await status in supabase.storage
    .from("avatars")
    .uploadStream(path: "public/avatar.png", file: fileData) {
    switch status {
    case .progress(let byteSent, let totalBytes):
        let percent = Double(byteSent) / Double(totalBytes) * 100
        print("Progress: \(percent)%")
    case .success(let response):
        print("Upload complete: \(response.fullPath)")
    }
}

Alternative Solutions

URLSession supports upload progress via URLSessionTaskDelegate.urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:). The upload must be initiated from a file URL (not in-memory Data) for the byte count to be known upfront. An AsyncStream wrapping a URLSession with a delegate would be a minimal, clean implementation.

Priority

Medium - Would significantly improve my workflow

Additional Context

No response

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions