Alamofire для Swift: полное руководство с примерами

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

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

Начать курс

Что такое Alamofire и зачем она нужна

Alamofire — это элегантная и мощная библиотека для работы с сетевыми запросами на языке Swift. Она предоставляет удобный интерфейс для выполнения HTTP-запросов, обработки ответов, загрузки и выгрузки данных, а также работы с аутентификацией и сериализацией. Написана на чистом Swift, поддерживает iOS, macOS, tvOS и watchOS.

Основные причины использовать Alamofire:

  • Простота использования — интуитивно понятный API, который сокращает количество кода по сравнению с URLSession.
  • Автоматическая сериализация — встроенная поддержка JSON, Property List и кастомных форматов.
  • Цепочки запросов — легко комбинировать несколько запросов и обрабатывать их последовательно.
  • Обработка ошибок — детальная информация об ошибках сети и сервера.
  • Поддержка SSL-пиннинга — безопасное соединение с сервером.
  • Загрузка файлов — поддержка прогресса и возобновления загрузки.
  • Активное сообщество — регулярные обновления и множество примеров.

Установка Alamofire

Alamofire устанавливается через Swift Package Manager (SPM), CocoaPods или Carthage. Рекомендуемый способ — SPM.

Установка через Swift Package Manager (SPM)

  1. В Xcode откройте проект: File → Add Packages...
  2. Вставьте URL репозитория: https://github.com/Alamofire/Alamofire.git
  3. Выберите версию (последнюю стабильную) и нажмите Add Package.
  4. Убедитесь, что пакет добавлен в ваш target.

Установка через CocoaPods

# Podfile
platform :ios, '13.0'
use_frameworks!

target 'YourApp' do
  pod 'Alamofire', '~> 5.9'
end

После этого выполните pod install.

Установка через Carthage

# Cartfile
github "Alamofire/Alamofire" ~> 5.9

Затем выполните carthage update --platform iOS.

Быстрый старт с примером кода

После установки импортируйте библиотеку и выполните простой GET-запрос:

import Alamofire

// Простой GET-запрос
AF.request("https://jsonplaceholder.typicode.com/posts/1")
    .responseJSON { response in
        switch response.result {
        case .success(let data):
            print("Полученные данные: \(data)")
        case .failure(let error):
            print("Ошибка: \(error.localizedDescription)")
        }
    }

Этот код отправляет запрос к тестовому API, получает JSON и выводит его в консоль. Alamofire автоматически обрабатывает URL-сессию, создание запроса и сериализацию ответа.

Основные методы и функции Alamofire

Рассмотрим 10 ключевых методов библиотеки с подробным описанием и примерами.

1. AF.request() — базовый HTTP-запрос

Что делает: Отправляет HTTP-запрос любого метода (GET, POST, PUT, DELETE и т.д.) на указанный URL.

Параметры:

  • _ url: URLConvertible — URL или строка URL.
  • method: HTTPMethod = .get — HTTP метод (get, post, put, delete, patch и др.).
  • parameters: Parameters? = nil — словарь параметров запроса.
  • encoding: ParameterEncoding = URLEncoding.default — способ кодирования параметров.
  • headers: HTTPHeaders? = nil — заголовки запроса.
  • interceptor: RequestInterceptor? = nil — перехватчик для модификации запроса.

Пример:

let parameters: [String: Any] = [
    "userId": 1,
    "title": "Новый пост",
    "body": "Текст поста"
]

AF.request("https://jsonplaceholder.typicode.com/posts",
           method: .post,
           parameters: parameters,
           encoding: JSONEncoding.default,
           headers: ["Content-Type": "application/json"])
    .responseJSON { response in
        print(response)
    }

2. AF.upload() — загрузка данных на сервер

Что делает: Загружает данные (файлы, Data, InputStream) на сервер с отслеживанием прогресса.

Параметры:

  • _ convertible: UploadConvertible — данные для загрузки (Data, URL, InputStream).
  • to convertible: URLConvertible — URL назначения.
  • method: HTTPMethod = .post — HTTP метод.
  • headers: HTTPHeaders? = nil — заголовки.
  • interceptor: RequestInterceptor? = nil — перехватчик.

Пример:

let fileURL = Bundle.main.url(forResource: "image", withExtension: "jpg")!

AF.upload(fileURL, to: "https://example.com/upload")
    .uploadProgress { progress in
        print("Прогресс загрузки: \(progress.fractionCompleted * 100)%")
    }
    .responseJSON { response in
        print("Ответ сервера: \(response)")
    }

3. AF.download() — скачивание файла

Что делает: Скачивает файл с сервера с поддержкой возобновления загрузки и отслеживанием прогресса.

Параметры:

  • _ url: URLConvertible — URL файла.
  • method: HTTPMethod = .get — HTTP метод.
  • parameters: Parameters? = nil — параметры запроса.
  • encoding: ParameterEncoding = URLEncoding.default — кодирование.
  • headers: HTTPHeaders? = nil — заголовки.
  • to destination: DownloadRequest.Destination? = nil — путь сохранения файла.

Пример:

let destination: DownloadRequest.Destination = { _, _ in
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = documentsURL.appendingPathComponent("downloaded_file.pdf")
    return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}

AF.download("https://example.com/sample.pdf", to: destination)
    .downloadProgress { progress in
        print("Скачано: \(progress.fractionCompleted * 100)%")
    }
    .responseURL { response in
        if let filePath = response.fileURL?.path {
            print("Файл сохранён по пути: \(filePath)")
        }
    }

4. responseJSON() — обработка JSON-ответа

Что делает: Сериализует ответ сервера в JSON (Any) и вызывает замыкание с результатом.

Параметры:

  • queue: DispatchQueue = .main — очередь для выполнения замыкания.
  • dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor — предобработчик данных.
  • emptyResponseCodes: Set<Int> = [204, 205] — коды для пустого ответа.
  • completionHandler: @escaping (AFDataResponse<Any>) -> Void — замыкание с результатом.

Пример:

AF.request("https://api.github.com/users/octocat")
    .responseJSON { response in
        switch response.result {
        case .success(let json):
            if let dict = json as? [String: Any], let login = dict["login"] as? String {
                print("Логин пользователя: \(login)")
            }
        case .failure(let error):
            print("Ошибка: \(error)")
        }
    }

5. responseDecodable() — декодирование в модель

Что делает: Автоматически декодирует JSON-ответ в указанную Decodable-структуру или класс.

Параметры:

  • type: T.Type — тип модели, реализующей Decodable.
  • queue: DispatchQueue = .main — очередь выполнения.
  • decoder: DataDecoder = JSONDecoder() — декодер (можно кастомный).
  • completionHandler: @escaping (AFDataResponse<T>) -> Void — замыкание с результатом.

Пример:

struct Post: Decodable {
    let id: Int
    let title: String
    let body: String
}

AF.request("https://jsonplaceholder.typicode.com/posts/1")
    .responseDecodable(of: Post.self) { response in
        switch response.result {
        case .success(let post):
            print("Пост #\(post.id): \(post.title)")
        case .failure(let error):
            print("Ошибка декодирования: \(error)")
        }
    }

6. validate() — валидация ответа

Что делает: Проверяет статус-код и содержимое ответа. Если код не в диапазоне 200-299, запрос считается неудачным.

Параметры:

  • statusCode: [Int]? = nil — допустимые коды (по умолчанию 200-299).
  • contentType: [String]? = nil — допустимые типы содержимого.

Пример:

AF.request("https://httpbin.org/status/404")
    .validate(statusCode: 200..<300)
    .response { response in
        if let error = response.error {
            print("Ошибка валидации: \(error.localizedDescription)")
        } else {
            print("Успех!")
        }
    }

7. authenticate() — HTTP-аутентификация

Что делает: Добавляет базовую HTTP-аутентификацию (username/password) к запросу.

Параметры:

  • username: String — имя пользователя.
  • password: String — пароль.
  • persistence: URLCredential.Persistence = .forSession — сохранять ли учётные данные.

Пример:

AF.request("https://httpbin.org/basic-auth/user/passwd")
    .authenticate(username: "user", password: "passwd")
    .responseJSON { response in
        print(response)
    }

8. cURLDescription() — отладка запроса

Что делает: Возвращает строку с cURL-представлением запроса для отладки.

Параметры:

  • Нет параметров (вызывается на объекте DataRequest).

Пример:

let request = AF.request("https://jsonplaceholder.typicode.com/posts")
print(request.cURLDescription())
// Вывод: curl -X GET "https://jsonplaceholder.typicode.com/posts" -H "Accept: */*"

9. responseString() — получение строки

Что делает: Сериализует ответ в строку с указанной кодировкой.

Параметры:

  • encoding: String.Encoding? = nil — кодировка (по умолчанию .utf8).
  • completionHandler: @escaping (AFDataResponse<String>) -> Void — замыкание.

Пример:

AF.request("https://example.com")
    .response                    

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