Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions