Налаштування Alamofire для мережевих запитів у iOS-додатках
URLSession достатній для простих запитів. Alamofire додає цінність там, де URLSession вимагає багато boilerplate: ланцюжки запитів, перехоплювачі авторизації, логіка повторних спроб, завантаження multipart, закріплення сертифікатів. Версія 5.x побудована на async/await та Combine зі збереженням зворотної сумісності.
Архітектура мережевого шару з Alamofire
Основна помилка — використання AF.request(...) безпосередньо з ViewModel або ViewController. Мережевий шар повинен бути ізольованим.
Правильна структура: APIClient (singleton або dependency-injected) → Router (enum з URLRequestConvertible) → Alamofire Session → моделі.
enum UserRouter: URLRequestConvertible {
case getProfile(id: String)
case updateProfile(UserUpdateRequest)
var method: HTTPMethod {
switch self {
case .getProfile: return .get
case .updateProfile: return .patch
}
}
func asURLRequest() throws -> URLRequest {
var request = try URLRequest(url: baseURL.appendingPathComponent(path))
request.method = method
return try encoder.encode(self, into: request)
}
}
Перехоплювач авторизації (RequestInterceptor)
Автоматичне оновлення access_token через refresh_token — без RequestInterceptor це означає десятки рядків у кожному запиті:
class AuthInterceptor: RequestInterceptor {
func adapt(_ urlRequest: URLRequest, for session: Session,
completion: @escaping (Result<URLRequest, Error>) -> Void) {
var request = urlRequest
request.headers.add(.authorization(bearerToken: tokenStore.accessToken))
completion(.success(request))
}
func retry(_ request: Request, for session: Session, dueTo error: Error,
completion: @escaping (RetryResult) -> Void) {
guard request.response?.statusCode == 401 else {
completion(.doNotRetry); return
}
refreshToken { result in
switch result {
case .success: completion(.retry)
case .failure(let e): completion(.doNotRetryWithError(e))
}
}
}
}
Session з цим перехоплювачем автоматично додає токен та повторює запит після оновлення — прозоро для коду, що викликає.
Декодування та обробка помилок
responseDecodable(of:) з JSONDecoder — стандартна практика. Користувацький JSONDecoder з dateDecodingStrategy та keyDecodingStrategy налаштовується один раз в APIClient.
Помилки сервера часто приходять у вигляді JSON з кодом та повідомленням. Користувацький ResponseSerializer або validate() + обробка в mapError:
session.request(router)
.validate(statusCode: 200..<300)
.responseDecodable(of: T.self, decoder: decoder) { response in
switch response.result {
case .success(let value): // ok
case .failure(let error):
if let data = response.data,
let apiError = try? decoder.decode(APIError.self, from: data) {
// показуємо apiError.message
}
}
}
Multipart та завантаження файлів
Завантажуйте зображення через upload(multipartFormData:):
session.upload(multipartFormData: { formData in
formData.append(imageData, withName: "photo", fileName: "photo.jpg", mimeType: "image/jpeg")
}, with: router)
.uploadProgress { progress in
updateProgressBar(progress.fractionCompleted)
}
uploadProgress виконується на main queue за замовчуванням під час вказання черги .main — інакше оновлюйте UI через DispatchQueue.main.async.
Закріплення сертифіката
Для додатків з чутливими даними налаштуйте закріплення сертифіката через ServerTrustManager:
let manager = ServerTrustManager(evaluators: [
"api.example.com": PinnedCertificatesTrustEvaluator()
])
let session = Session(serverTrustManager: manager)
Зберігайте сертифікати в Bundle. При ротації сертифіката сервера потрібно оновити додаток — без цього всі запити виходять з помилкою SSL error. Тому в enterprise-проектах часто використовують закріплення публічного ключа замість повного сертифіката.
Що входить у роботу
- Налаштування
Sessionз користувацькимRequestInterceptorдля авторизації -
Routerна основіURLRequestConvertibleдля всіх кінцевих точок - Користувацький
JSONDecoderз необхідними стратегіями - Обробка мережевих та серверних помилок
- Завантаження файлів з прогресом
- Опціонально: закріплення сертифіката, перехоплювач логування
Терміни
Базовий мережевий шар із маршрутизатором та авторизацією: 1 день. З multipart, SSL pinning, стратегією повтору та повним покриттям помилок: 2–3 дні. Ціна розраховується індивідуально.







