Работа с S3 и облачными хранилищами в Swift (iOS/macOS): библиотека AWSS3

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с S3 и облачными хранилищами в Swift (iOS/macOS)

В современной разработке под iOS и macOS часто возникает необходимость интегрировать облачные хранилища, совместимые с протоколом Amazon S3 (Simple Storage Service). Это может быть как официальный AWS S3, так и self-hosted решения вроде MinIO или DigitalOcean Spaces. Для Swift существует мощный инструмент — библиотека AWSS3 из состава AWS SDK for Swift, которая позволяет легко управлять объектами в бакетах: загружать, скачивать, удалять и получать метаданные.

В этой статье мы разберём, как настроить AWSS3 в проекте, выполнить базовые операции с файлами и обработать возможные ошибки. Материал подойдёт для iOS и macOS приложений, написанных на Swift 5.7+.

Установка и настройка AWSS3

Для работы с AWSS3 необходимо добавить зависимость через Swift Package Manager (SPM) или CocoaPods. Рассмотрим SPM — самый современный способ.

  1. Откройте Xcode, перейдите в File → Add Packages...
  2. Введите URL репозитория: https://github.com/awslabs/aws-sdk-swift.git
  3. Выберите пакет AWSS3 и укажите версию (рекомендуется последняя стабильная).
  4. Добавьте пакет в целевой таргет.

После установки импортируйте модуль в файл, где будет происходить работа с хранилищем:

import AWSS3

Конфигурация клиента S3

Для подключения к S3-совместимому хранилищу необходимо создать конфигурацию с учётными данными (Access Key, Secret Key) и endpoint'ом. Для AWS S3 endpoint можно не указывать — SDK автоматически определит регион. Для MinIO или других сервисов endpoint обязателен.

// Пример конфигурации для MinIO (локальный сервер)
let endpoint = "http://localhost:9000"
let accessKey = "YOUR_ACCESS_KEY"
let secretKey = "YOUR_SECRET_KEY"

let credentials = AWSCredentials(accessKey: accessKey, secretAccessKey: secretKey)
let region = AWSRegion.useast1 // или другой регион

let configuration = AWSS3Configuration(
    region: region,
    endpoint: endpoint,
    credentialsProvider: .static(credentials),
    useFIPS: false,
    useDualStack: false
)

let s3Client = try await AWSS3Client(configuration: configuration)

Для AWS S3 конфигурация проще — достаточно указать регион и получить credentials из IAM-роли или переменных окружения:

let configuration = AWSS3Configuration(
    region: .useast1,
    credentialsProvider: .default
)
let s3Client = try await AWSS3Client(configuration: configuration)

Основные операции с объектами S3

1. Загрузка файла (Upload)

Для загрузки данных в бакет используйте метод putObject. Данные могут быть Data, String или потоком.

func uploadFile(bucket: String, key: String, data: Data) async throws {
    let putObjectInput = PutObjectInput(
        body: .data(data),
        bucket: bucket,
        key: key
    )
    let response = try await s3Client.putObject(input: putObjectInput)
    print("Файл загружен. ETag: \(response.eTag ?? "неизвестно")")
}

2. Скачивание файла (Download)

Для получения объекта используйте getObject:

func downloadFile(bucket: String, key: String) async throws -> Data {
    let getObjectInput = GetObjectInput(
        bucket: bucket,
        key: key
    )
    let response = try await s3Client.getObject(input: getObjectInput)
    guard let body = response.body else {
        throw NSError(domain: "S3Error", code: -1, userInfo: [NSLocalizedDescriptionKey: "Пустое тело ответа"])
    }
    let data = try await body.readData()
    return data
}

3. Получение списка объектов в бакете

Метод listObjectsV2 возвращает список ключей (имён файлов) в бакете:

func listFiles(bucket: String) async throws -> [String] {
    let listInput = ListObjectsV2Input(bucket: bucket)
    let response = try await s3Client.listObjectsV2(input: listInput)
    return response.contents?.compactMap { $0.key } ?? []
}

4. Удаление объекта

func deleteFile(bucket: String, key: String) async throws {
    let deleteInput = DeleteObjectInput(bucket: bucket, key: key)
    _ = try await s3Client.deleteObject(input: deleteInput)
    print("Файл \(key) удалён")
}

Работа с облачными хранилищами, совместимыми с S3

Библи

Рекомендаций