URLSession — какво е това, мрежов API и как работи в iOS

Автор: IT Sectr Публикувано: 2026-03-07 Време за четене: 8 мин

URLSession — е API за мрежови заявки в iOS и macOS, част от Foundation framework, предоставящ унифициран интерфейс за работа с HTTP, HTTPS, фоново изтегляне и WebSocket. Той замени остарелия NSURLConnection и се превърна в основния мрежов инструмент за Apple разработчиците. Според Apple Developer Documentation (2025), URLSession обработва над 90% от мрежовия трафик в приложенията за iPhone и iPad.

Основни неща

  • URLSession — роден Apple API за мрежови заявки, HTTP, изтегляне на файлове и WebSocket
  • Типове задачи: dataTask (заявки), downloadTask (изтегляне), uploadTask (качване), webSocketTask
  • Конфигурация на сесията определя поведението: кеширане, тайм-аути, прокси, идентификационни данни
  • Асинхронност се реализира чрез closures, делегати или модерния async/await
  • Фонови сесии позволяват изтегляне на данни дори когато приложението е минимизирано

Какво е URLSession?

URLSession — е API за мрежови операции, представен от Apple в iOS 7 и macOS 10.9. Той замени NSURLConnection и предостави по-гъвкав и мощен модел за работа с мрежата. Библиотеката поддържа HTTP/1.1, HTTP/2, HTTP/3 и WebSocket, както и фонови сесии за изтегляне на данни.

Основното предимство на URLSession пред стария NSURLConnection — поддръжка на множество едновременни връзки чрез единична сесия, конфигурируеми настройки и възможност за спиране и възобновяване на изтегляния. Сесия обединява група от мрежови задачи с общи настройки: кеширане, политика за бисквитки, тайм-аути, TLS сертификати.

В iOS URLSession работи със системния DNS кеш, управлението на енергията и фоновите процеси. Когато приложението е минимизирано, системата може да продължи изтеглянето на данни чрез фонова сесия, а след завършване да уведоми приложението чрез handler за завършване. Фоновите сесии са особено полезни за изтегляне на големи файлове, актуализиране на съдържание и синхронизиране на данни в приложения за работа с документи и медийни файлове. За работа с фонови сесии трябва да се имплементира делегат URLSessionDelegate и да се предаде идентификатор на конфигурацията при създаване на сесията — системата използва този идентификатор за възстановяване на сесията след рестартиране на приложението.

Важно предимство на URLSession е поддръжката на HTTP/2 и HTTP/3. Мултиплексирането на HTTP/2 позволява изпращане на множество заявки чрез една TCP връзка, което намалява забавянето и натоварването на сървъра. HTTP/3, базиран на протокола QUIC върху UDP, осигурява още по-бързо установяване на връзка чрез елиминиране на TCP ръкостискането.

Архитектура на URLSession

Архитектурата на URLSession се състои от три ключови компонента: конфигурация на сесията, самата сесия и задачи (tasks). Всеки компонент отговаря за свой аспект на мрежовото взаимодействие и комбинацията им определя поведението на приложението при работа с мрежата.

URLSessionConfiguration

Конфигурацията задава параметрите на сесията — от тайм-аути до политики за кеширане. Съществуват три типа: .default (стандартна с дисков кеш), .ephemeral (без запазване на кеш и бисквитки) и .background (за фоново изтегляне). В конфигурацията могат да се зададат максимален брой връзки на хост, тайм-аут на заявка и ресурс, TLS политика и прокси.

Типове задачи URLSessionTask

URLSessionTask — базов клас за всички мрежови операции. Основните подкласове: URLSessionDataTask за GET и POST заявки с връщане на данни в паметта, URLSessionDownloadTask за изтегляне на файлове на диска, URLSessionUploadTask за изпращане на файлове към сървъра и URLSessionWebSocketTask за работа с WebSocket от iOS 13.

Делегати на URLSession

Делегатът на сесията получава събития за напредъка на задачите: получаване на данни, завършване на изтегляне, грешки при удостоверяване, пренасочвания. URLSessionDelegate и неговите подпротоколи позволяват прихващане на TLS сертификати при удостоверяване, управление на кеширане на отговори чрез URLCache и наблюдение на напредъка при изтегляне на големи файлове. Алтернативно, могат да се използват closures (completion handlers) в прости случаи, когато не се изисква обработка на междинни събития.

Как да изпълнявате заявки с URLSession

Основният сценарий за работа с URLSession изглежда така: създава се конфигурация, на нейна основа — сесия, след това чрез сесията се създава задача с URL заявка и задачата се стартира. Нека разгледаме пример за GET заявка с closure. Този модел се използва в повечето iOS приложения за получаване на данни от REST API, зареждане на изображения и взаимодействие с облачни услуги.

swift
let url = URL(string: "https://api.example.com/users")!
let session = URLSession.shared
let task = session.dataTask(with: url) { data, response, error in
    guard let data = data, error == nil else {
        print("Грешка: \(error!.localizedDescription)")
        return
    }
    if let json = try? JSONSerialization.jsonObject(with: data) {
        print("JSON: \(json)")
    }
}
task.resume()

В примера се използва URLSession.shared — сингълтън с .default конфигурация за прости заявки. dataTask създава асинхронна операция, но не я стартира — задължително трябва да се извика resume(). Closure се изпълнява след завършване на заявката и връща data, response или error. За персонализирана сесия със собствена конфигурация използвайте инициализатора URLSession(configuration:), който позволява задаване на политики за кеширане, тайм-аути, максимален брой връзки, подразбиращи се HTTP заглавки и прокси настройки за всички задачи на сесията. Този подход предоставя пълен контрол върху мрежовото поведение в приложението.

Изтегляне на файлове чрез URLSession

URLSession поддържа изтегляне на файлове с възможност за спиране и възобновяване, както и фоново изтегляне. DownloadTask записва файла в временна директория, а в closure за завършване трябва да се премести на постоянно място.

swift
let url = URL(string: "https://example.com/file.zip")!
let session = URLSession(configuration: .default)
let task = session.downloadTask(with: url) { location, _, _ in
    guard let location = location else { return }
    let destination = FileManager.default.temporaryDirectory
        .appendingPathComponent("file.zip")
    try? FileManager.default.moveItem(at: location, to: destination)
}
task.resume()

Параметърът location в closure указва временния файл, който трябва да се премести, в противен случай системата ще го изтрие след излизане от closure. За проследяване на напредъка се използва делегат URLSessionDownloadDelegate с метода didWriteData, който предава броя записани байтове и общия размер на файла — тези данни могат да се използват за показване на лента за напредък в потребителския интерфейс. Фоновите сесии с downloadTask позволяват продължаване на изтеглянето дори след минимизиране на приложението, а след завършване системата извиква handler в AppDelegate.

URLSession срещу Alamofire

Alamofire — е Swift библиотека, изградена върху URLSession, която предоставя по-декларативен интерфейс. Изборът между родния API и Alamofire зависи от сложността на проекта и предпочитанията на екипа.

КритерийURLSessionAlamofire
ЗависимостиНяма, вграден във FoundationИзисква SPM или CocoaPods
СинтаксисИмперативен с closuresДекларативен с вериги
Обработка на JSONJSONSerialization ръчноresponseDecodable с Codable
ПрихващачиЧрез делегатиRequestInterceptor, EventMonitor
НапредъкЧрез делегатdownloadProgress, uploadProgress

За прости проекти URLSession е достатъчен и не добавя зависимости. Alamofire е оправдан в проекти с множество мрежови заявки, сложна обработка на грешки и изискване за кратък синтаксис. И двете технологии използват общата основа URLSessionConfiguration и са съвместими помежду си. При избора трябва да се вземе предвид, че URLSession се контролира изцяло от Apple и се актуализира заедно с iOS, докато Alamofire изисква поддръжка на съвместимост с нови версии на ОС от страна на разработчиците на библиотеката.

Примери за код на URLSession

Модерният Swift поддържа async/await, който прави мрежовите заявки по-четими в сравнение с closures. Нека разгледаме същата GET заявка, използвайки асинхронен синтаксис.

swift
func fetchUsers() async throws -> [User] {
    let url = URL(string: "https://api.example.com/users")!
    let (data, _) = try await URLSession.shared.data(from: url)
    let users = try JSONDecoder().decode([User].self, from: data)
    return users
}

Методът data(from:) е достъпен от iOS 15 и macOS 12. Той връща кортеж (Data, URLResponse) и хвърля грешка при мрежови проблеми. JSONDecoder с Codable модел автоматично десериализира отговора — това заменя тромавия JSONSerialization от предишния пример.

POST заявка с JSON тяло

За POST заявки с JSON тяло се използва URLRequest, в който се конфигурират методът, Content-Type заглавките и тялото на заявката като Data. Async/await прави този процес кратък и ясен, а обработката на грешки е проста чрез do-catch блок.

swift
func createUser(name: String) async throws -> User {
    var request = URLRequest(url: URL(string: "https://api.example.com/users")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let body = try JSONEncoder().encode(["name": name])
    request.httpBody = body
    let (data, _) = try await URLSession.shared.data(for: request)
    return try JSONDecoder().decode(User.self, from: data)
}

Често задавани въпроси

Как URLSession се различава от NSURLConnection?

URLSession е модерният заместител на NSURLConnection, представен в iOS 7. Основни разлики: поддръжка на множество връзки чрез сесии, спиране и възобновяване на задачи, фоново изтегляне и WebSocket. NSURLConnection е остарял и не се препоръчва за използване в нови проекти.

Как да проследя напредъка на изтегляне в URLSession?

За проследяване на напредъка се използва делегат URLSessionDownloadDelegate с метода urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite). Алтернативно, за dataTask можете да се абонирате за URLSessionTaskDelegate и да получавате актуализации чрез didSendBodyData.

Как да изпълня фоново изтегляне с URLSession?

Фоновото изтегляне се конфигурира чрез .background(withIdentifier:). Приложението регистрира handler за завършване в AppDelegate и получава резултати дори след минимизиране или затваряне. Системата управлява изтеглянето и уведомява приложението чрез делегата sessionDidFinishEvents.

Може ли URLSession да се използва с WebSocket?

Да, от iOS 13 URLSession поддържа WebSocket чрез класа URLSessionWebSocketTask. Създава се чрез метода webSocketTask(with:) и предоставя методи send, receive с поддръжка на текстови и двоични съобщения, както и ping/pong за поддържане на връзката.

Как да настроя тайм-аут в URLSession?

Тайм-аутите се настройват чрез URLSessionConfiguration: свойствата timeoutIntervalForRequest (изчакване на отговор на заявка) и timeoutIntervalForResource (максимално време за цялото изтегляне). По подразбиране: 60 секунди за заявка и 7 дни за ресурс.

Резюме

  • URLSession — роден Apple API за мрежови заявки, поддържащ HTTP, фоново изтегляне и WebSocket
  • Три типа конфигурация (.default, .ephemeral, .background) определят поведението на сесията
  • Четири типа задачи покриват всички сценарии: dataTask, downloadTask, uploadTask, webSocketTask
  • Делегати позволяват управление на удостоверяване, напредък и пренасочвания
  • Async/await от iOS 15 прави URLSession кода по-четлив и кратък
  • Избор на URLSession или Alamofire зависи от мащаба на проекта — URLSession е достатъчен за прости задачи

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също