Как выполнить сетевой запрос в iOS с помощью URLSession?

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

Ответ

URLSession — это основной фреймворк iOS для выполнения сетевых запросов. Он поддерживает различные типы задач (data, download, upload) и предоставляет мощные возможности конфигурации и делегирования.

Базовый GET-запрос с обработкой JSON:

// 1. Определяем endpoint
let url = URL(string: "https://api.example.com/users")!

// 2. Создаем Data Task
let task = URLSession.shared.dataTask(with: url) { data, response, error in
    // 3. Обрабатываем ошибку сети
    if let error = error {
        print("Network error: (error)")
        return
    }

    // 4. Проверяем HTTP-статус ответа
    guard let httpResponse = response as? HTTPURLResponse,
          (200...299).contains(httpResponse.statusCode) else {
        print("Server returned an error")
        return
    }

    // 5. Проверяем наличие данных
    guard let data = data else { return }

    // 6. Декодируем JSON в модель (используя Codable)
    do {
        let users = try JSONDecoder().decode([User].self, from: data)
        // 7. Обновляем UI в главном потоке
        DispatchQueue.main.async {
            self.updateUI(with: users)
        }
    } catch {
        print("JSON decoding failed: (error)")
    }
}

// 8. Запускаем задачу (задачи по умолчанию приостановлены)
task.resume()

Расширенные возможности:

  • Создание запроса (URLRequest): Позволяет задать метод (POST, PUT), заголовки и тело запроса.

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try? JSONEncoder().encode(postData)
  • Кастомная конфигурация (URLSessionConfiguration): Можно настроить таймауты, политики кэширования, использовать фоновую сессию.

    let config = URLSessionConfiguration.default
    config.timeoutIntervalForRequest = 30
    config.requestCachePolicy = .reloadIgnoringLocalCacheData
    let session = URLSession(configuration: config)
  • Современные подходы:

    • Async/await (iOS 15+): Упрощает код, избавляя от completion handlers.
      let (data, response) = try await URLSession.shared.data(from: url)
    • Combine: Позволяет работать с сетевыми запросами как с издателями (publishers).