Работа с 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 — самый современный способ.
- Откройте Xcode, перейдите в
File → Add Packages... - Введите URL репозитория:
https://github.com/awslabs/aws-sdk-swift.git - Выберите пакет
AWSS3и укажите версию (рекомендуется последняя стабильная). - Добавьте пакет в целевой таргет.
После установки импортируйте модуль в файл, где будет происходить работа с хранилищем:
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
Библи