Какой у вас опыт проектирования сетевого слоя и клиентов для REST API в iOS?

«Какой у вас опыт проектирования сетевого слоя и клиентов для REST API в iOS?» — вопрос из категории Сети, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, есть опыт проектирования и реализации сетевого слоя для взаимодействия с REST API. Основной подход — создание абстракций для разделения ответственности, обработки ошибок и упрощения тестирования.

Ключевые компоненты архитектуры:

  1. Протокол сервиса — определяет контракт для сетевых операций.
  2. Модели данных (Codable) — для сериализации/десериализации JSON.
  3. Менеджер запросов — инкапсулирует логику вызовов (URLSession/Alamofire).
  4. Обработчик ошибок — преобразует сетевые и HTTP-ошибки в доменные.

Пример базовой реализации на URLSession:

protocol APIClient {
    func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T
}

final class NetworkService: APIClient {
    private let session: URLSession
    private let decoder: JSONDecoder

    init(session: URLSession = .shared, decoder: JSONDecoder = JSONDecoder()) {
        self.session = session
        self.decoder = decoder
    }

    func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T {
        let request = try endpoint.urlRequest()
        let (data, response) = try await session.data(for: request)

        guard let httpResponse = response as? HTTPURLResponse,
              (200...299).contains(httpResponse.statusCode) else {
            throw APIError.invalidResponse
        }
        return try decoder.decode(T.self, from: data)
    }
}

// Использование
let service = NetworkService()
let user: User = try await service.request(.getUser(id: 123))

Best Practices, которые я применяю:

  • Инъекция зависимостей для URLSession и JSONDecoder (упрощает тестирование).
  • Generic-методы для типобезопасного декодирования ответов.
  • Централизованная обработка ошибок (сетевые, HTTP-статусы, декодирование).
  • Конфигурация кеширования через URLCache для оптимизации.
  • Модульные тесты с мокированием через URLProtocol.
  • Для сложных API рассматриваю кодогенерацию из OpenAPI-спецификаций (Swagger).