Skip to main content

Upload Methods

r2Vault supports three ways to upload files to your R2 bucket:

Drag & Drop

Drop files from Finder directly into the browser window

File Picker

Click the + button and choose Upload Files…

Menu Bar Widget

Drop files into the menu bar drop zone for instant upload

Drag-and-Drop from Finder

The fastest way to upload files:
1

Select files in Finder

Choose one or more files (or an entire folder)
2

Drag to r2Vault

Drop them anywhere in the browser window. A blue overlay appears when the drop zone is active.
3

Upload begins

Files are queued and uploaded concurrently with live progress.
Files are uploaded to the current folder shown in the breadcrumb path. Navigate to a folder first to upload files there.

Folder Uploads

Dragging a folder recursively enumerates all files and preserves the folder structure:
Drop: vacation/
  ├── photos/
  │   ├── beach.jpg
  │   └── sunset.png
  └── videos/
      └── drone.mp4

Uploaded as:
  vacation/photos/beach.jpg
  vacation/photos/sunset.png
  vacation/videos/drone.mp4
Source: AppViewModel.swift:360-420 (source: Fiaxe/ViewModels/AppViewModel.swift:360-420)

Upload Files Button

Use the toolbar button for more control:
1

Click the + button

Opens the upload menu with options:
  • Upload Files…
  • Upload Folder…
  • New Folder…
2

Choose Upload Files…

Opens the macOS file picker
3

Select files

Choose one or more files. Press ⌘A to select all, or ⌘-click for multi-select.
4

Confirm

Click Open to start the upload
The file picker uses security-scoped bookmarks to preserve access to files even after the picker closes, enabling background uploads.
Implementation: AppViewModel.swift:458-469 (source: Fiaxe/ViewModels/AppViewModel.swift:458-469)

Concurrent Uploads with Progress

Uploads run in parallel for maximum speed:

Queue Behavior

  • Up to multiple files upload simultaneously
  • Each upload has its own progress bar
  • Queue updates in real-time as files complete
  • Failed uploads stay in the queue for review

Progress Display

The browser refreshes automatically when uploads complete, showing newly added files.
Source: MenuBarView.swift:188-221 (source: Fiaxe/Views/MenuBarView.swift:188-221)

Upload Lifecycle

StatusDescription
PendingQueued, waiting for an available slot
UploadingActive transfer with live progress
CompletedSuccessfully uploaded to R2
FailedHTTP error or network issue
CancelledUser cancelled via Cancel button
Source: UploadTask.swift:23-29 (source: Fiaxe/Models/UploadTask.swift:23-29)

Canceling Uploads

Stop uploads in progress:
From the menu bar widget, click the × button next to any uploading file.
Click Cancel All in the menu bar upload progress section.
Cancelled uploads are not retried automatically. Partially uploaded data may remain in R2 until the object is completed or manually deleted.
Cancellation implementation: UploadTask.swift:41-45 (source: Fiaxe/Models/UploadTask.swift:41-45)

Auto-Copy Public URL to Clipboard

When an upload completes successfully:
1

Upload finishes

File is written to R2 and appears in the browser
2

URL generated

r2Vault constructs the public URL:
  • Uses custom domain if configured
  • Falls back to R2 endpoint: https://<account>.r2.cloudflarestorage.com/<bucket>/<key>
3

Clipboard copy

URL is automatically copied to the system clipboard
4

Toast notification

A green toast appears in the menu bar:
✓ Link copied!
photo.jpg
No extra clicks needed — paste the URL immediately into your browser, Slack, or anywhere else!
Source: AppViewModel.swift:559-578 (source: Fiaxe/ViewModels/AppViewModel.swift:559-578)

Custom Domain URLs

If you’ve configured a custom domain in Settings:
- https://abc123.r2.cloudflarestorage.com/my-bucket/photo.jpg
+ https://cdn.example.com/photo.jpg
The custom domain URL is used for:
  • Clipboard auto-copy
  • Upload history
  • “Copy URL” context menu action
Implementation: R2Credentials.swift:36-45 (source: Fiaxe/Models/R2Credentials.swift:36-45)

Upload Service Details

Uploads use the S3-compatible PUT API with AWS Signature Version 4:
  • Method: PUT
  • Endpoint: https://<account>.r2.cloudflarestorage.com/<bucket>/<key>
  • Headers:
    • Content-Type: MIME type (auto-detected from file extension)
    • Content-Length: File size in bytes
    • Authorization: AWS4-HMAC-SHA256 signature
Uses URLSessionTaskDelegate to receive real-time byte counts:
func urlSession(
    _ session: URLSession,
    task: URLSessionTask,
    didSendBodyData bytesSent: Int64,
    totalBytesSent: Int64,
    totalBytesExpectedToSend: Int64
)
Progress is calculated as totalBytesSent / totalBytesExpectedToSend.
Uploads fail if:
  • HTTP status code is not 2xx
  • Network connection is lost
  • Task is cancelled by user
  • File permissions prevent reading
Error messages are displayed in the upload queue.
Source: R2UploadService.swift:19-50 (source: Fiaxe/Services/R2UploadService.swift:19-50)

Next Steps