Skip to main content

Overview

R2BrowseService provides S3-compatible ListObjectsV2, folder creation, and delete operations for Cloudflare R2. The service handles pagination, virtual folder management, and recursive object enumeration.
Located at: Fiaxe/Services/R2BrowseService.swift:12

Type Definition

Implemented as a nonisolated enum to allow calling from any actor context.

Methods

listObjects()

Lists objects and virtual folders at a given prefix (one level deep with delimiter).
R2Credentials
required
R2 credentials for authentication.
String
default:""
Prefix to filter objects by. Use empty string for root level, or "folder/" for a specific folder.
Returns: ListResult containing objects, folders, and pagination info. Throws: R2BrowseError or URLError if the request fails.

Implementation Details

The method automatically handles pagination by fetching all pages:
Each page uses the S3 ListObjectsV2 API with:
  • list-type=2 parameter
  • delimiter=/ to create virtual folders
  • prefix to scope the listing
  • continuation-token for pagination

listAllKeys()

Lists every object key that starts with a prefix (fully recursive, no delimiter).
R2Credentials
required
R2 credentials for authentication.
String
required
Prefix to filter objects by. All objects starting with this prefix will be returned, including nested objects.
Returns: Array of all object keys matching the prefix. Throws: R2BrowseError or URLError if the request fails.

Implementation Details

This method performs a flat listing without the delimiter parameter, allowing recursive enumeration:
Useful for operations that need to enumerate all nested objects (e.g., deleting a folder recursively).

createFolder()

Creates a virtual folder by putting a zero-byte object with a trailing slash.
R2Credentials
required
R2 credentials for authentication.
String
required
Folder key to create. Trailing slash is added automatically if not present. Example: "documents" or "documents/".
Throws: R2BrowseError if the creation fails.

Implementation Details

Folders in S3/R2 are virtual - they’re represented by zero-byte objects with a trailing slash and application/x-directory content type.

deleteObject()

Deletes an object by key.
R2Credentials
required
R2 credentials for authentication.
String
required
Object key to delete. Can be a file or folder (with trailing slash).
Throws: R2BrowseError if the deletion fails.

Implementation Details

Accepts both 2xx and 204 (No Content) as success codes.

Data Types

ListResult

Result from a ListObjectsV2 call.
[R2Object]
Array of file objects returned from the <Contents> elements in the XML response.
[R2Object]
Array of virtual folder objects from the <CommonPrefixes> elements. Only present when using a delimiter.
Bool
Whether there are more results available. Always false after listObjects() completes all pagination.
String?
Token for fetching the next page. nil when all results have been retrieved.

R2BrowseError

Errors thrown by the browse service.
(Int, String)
HTTP error with status code and response body. Example: httpError(403, "Access Denied").
String
XML parsing error with description.

URL Building

The service includes a private URL builder that correctly handles percent-encoding:
This preserves trailing slashes and correctly encodes special characters in object keys.

XML Parsing

The service includes two custom XML parsers:

ListBucketResultParser

Parses the S3 ListObjectsV2 XML response with delimiter:
  • Extracts <Contents> elements as file objects
  • Extracts <CommonPrefixes> elements as folder objects
  • Handles <IsTruncated> and <NextContinuationToken> for pagination
  • Parses ISO8601 dates with fractional seconds

FlatListParser

Parses the S3 ListObjectsV2 XML response without delimiter:
  • Extracts only object keys from <Contents> elements
  • Used by listAllKeys() for recursive enumeration
  • Handles pagination tokens

Usage Examples