← Назад к вопросам

На чем построено сетевое взаимодействие на текущем проекте?

1.0 Junior🔥 81 комментариев
#Работа с сетью

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Архитектура сетевого взаимодействия на текущем проекте

На текущем проекте сетевое взаимодействие построено на многоуровневой архитектуре, сочетающей нативные инструменты Apple и современные архитектурные паттерны. Это обеспечивает высокую производительность, безопасность и удобство сопровождения. Основой служит фреймворк URLSession, но с абстракциями, соответствующим принципам SOLID и Clean Architecture.

Основные компоненты

1. Модуль сетевого слоя (Network Layer)

На нижнем уровне используется кастомная обертка над URLSession, реализующая протоколо-ориентированный подход. Это позволяет легко подменять реализации для тестирования и поддержки различных типов запросов.

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

final class NetworkService: NetworkServiceProtocol {
    private let session: URLSession
    private let decoder: JSONDecoder
        
    init(session: URLSession = .shared) {
        self.session = session
        self.decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
    }
        
    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 NetworkError.invalidResponse
        }
            
        return try decoder.decode(T.self, from: data)
    }
}

2. Модель Endpoint

Каждый API-запрос инкапсулирован в структуру, соответствующую протоколу Endpoint. Это обеспечивает централизованное управление заголовками, параметрами, методом и путем.

protocol Endpoint {
    var baseURL: URL { get }
    var path: String { get }
    var method: HTTPMethod { get }
    var headers: [String: String]? { get }
    var parameters: [String: Any]? { get }
}

extension Endpoint {
    func urlRequest() throws -> URLRequest {
        let url = baseURL.appendingPathComponent(path)
        var request = URLRequest(url: url)
        request.httpMethod = method.rawValue
        request.allHTTPHeaderFields = headers
        
        // Добавление токена авторизации из Keychain
        if let token = AuthService.shared.accessToken {
            request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        }
        
        if let parameters = parameters {
            switch method {
            case .get:
                var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
                components?.queryItems = parameters.map { 
                    URLQueryItem(name: $0.key, value: "\($0.value)") 
                }
                request.url = components?.url
            default:
                request.httpBody = try JSONSerialization.data(withJSONObject: parameters)
            }
        }
        return request
    }
}

3. Интеграция с DTO / Codable

Все сетевые модели реализованы через DTO (Data Transfer Object) с использованием Codable для автоматической сериализации/десериализации. Это минимизирует бойлерплейт и ошибки парсинга.

struct UserDTO: Codable {
    let id: Int
    let username: String
    let email: String
    let createdAt: Date
    
    enum CodingKeys: String, CodingKey {
        case id, username, email
        case createdAt = "created_at"
    }
}

Ключевые особенности реализации:

  • Асинхронность: Активное использование Swift Concurrency (async/await) вместо callback'ов, что делает код линейным и читаемым
  • Обработка ошибок: Единая иерархия ошибок с категориями для сетевых сбоев, ошибок парсинга и бизнес-логики
  • Кэширование: Двухуровневое кэширование: в памяти через NSCache для частых запросов и на диске через CoreData для данных, требующих персистентности
  • Безопасность:
    • Использование SSL Pinning для критичных эндпоинтов
    • Хранение токенов в Keychain Services
    • Динамическая подгрузка конфигураций сервера через Remote Config
  • Мониторинг: Интеграция с MetricKit и кастомной системой логирования для отслеживания производительности сетевых запросов
  • Модульные тесты: Полное покрытие сетевого слоя юнит-тестами с моками через Protocol Mocks
  • Поддержка фоновых загрузок: URLSession сконфигурирован для поддержки загрузок в фоновом режиме для медиафайлов

Преимущества текущего подхода:

  1. Гибкость: Легко добавлять новые эндпоинты без изменения существующего кода
  2. Тестируемость: Все компоненты изолированы и могут быть протестированы отдельно
  3. Масштабируемость: Архитектура позволяет легко добавлять новые функции (пагинация, retry-логика, офлайн-режим)
  4. Производительность: Оптимизированное использование пула соединений и кэширование
  5. Безопасность: Современные практики защиты данных и аутентификации

Данная архитектура доказала свою эффективность в проекте с более чем 100 различными API