URLSession è un'API per richieste di rete in iOS e macOS, parte del framework Foundation che fornisce un'interfaccia unificata per lavorare con HTTP, HTTPS, download in background e WebSocket. Ha sostituito il obsoleto NSURLConnection ed è diventato il principale strumento di rete per gli sviluppatori Apple. Secondo Apple Developer Documentation (2025), URLSession gestisce oltre il 90% del traffico di rete nelle applicazioni iPhone e iPad.
Punti chiave
URLSession è un'API per operazioni di rete introdotta da Apple in iOS 7 e macOS 10.9. Ha sostituito NSURLConnection e ha fornito un modello più flessibile e potente per lavorare con la rete. La libreria supporta HTTP/1.1, HTTP/2, HTTP/3 e WebSocket, oltre a sessioni in background per il caricamento dei dati.
Il vantaggio principale di URLSession rispetto al vecchio NSURLConnection è il supporto per molteplici connessioni simultanee attraverso una singola sessione, configurazioni personalizzabili e la possibilità di mettere in pausa e riprendere i download. Una sessione raggruppa un insieme di attività di rete con impostazioni condivise: cache, politica dei cookie, timeout, certificati TLS.
In iOS, URLSession funziona con la cache DNS di sistema, la gestione dell'alimentazione e i processi in background. Quando l'app è ridotta a icona, il sistema può continuare a caricare dati attraverso una sessione in background e, al completamento, notificare l'app tramite un gestore di completamento. Le sessioni in background sono particolarmente utili per scaricare file di grandi dimensioni, aggiornare contenuti e sincronizzare dati in applicazioni di documenti e media. Per lavorare con sessioni in background, è necessario implementare URLSessionDelegate e passare un identificatore di configurazione durante la creazione della sessione — il sistema utilizza questo identificatore per ripristinare la sessione dopo un riavvio dell'app.
Un importante vantaggio di URLSession è il supporto per HTTP/2 e HTTP/3. Il multiplexing HTTP/2 consente di inviare più richieste attraverso una singola connessione TCP, riducendo la latenza e il carico del server. HTTP/3, basato sul protocollo QUIC su UDP, fornisce un'instaurazione della connessione ancora più rapida eliminando l'handshake TCP.
L'architettura di URLSession è composta da tre componenti chiave: configurazione della sessione, la sessione stessa e le attività. Ogni componente è responsabile di un aspetto dell'interazione di rete e la loro combinazione determina il comportamento dell'applicazione quando lavora con la rete.
La configurazione imposta i parametri della sessione — dai timeout alle politiche di cache. Esistono tre tipi: .default (standard con cache su disco), .ephemeral (senza salvare cache e cookie) e .background (per download in background). Nella configurazione è possibile specificare il numero massimo di connessioni per host, il timeout di richiesta e risorsa, la politica TLS e le impostazioni del proxy.
URLSessionTask è la classe base per tutte le operazioni di rete. Le principali sottoclassi sono: URLSessionDataTask per richieste GET e POST che restituiscono dati in memoria, URLSessionDownloadTask per scaricare file su disco, URLSessionUploadTask per caricare file sul server e URLSessionWebSocketTask per lavorare con WebSocket da iOS 13.
Il delegato di sessione riceve eventi sull'avanzamento delle attività: ricezione dati, completamento download, errori di autenticazione, reindirizzamenti. URLSessionDelegate e i suoi sottoprotocolli consentono di intercettare certificati TLS durante l'autenticazione, gestire la cache delle risposte tramite URLCache e monitorare l'avanzamento del download di file di grandi dimensioni. In alternativa, è possibile utilizzare closure (gestori di completamento) per casi semplici in cui non è richiesta la gestione di eventi intermedi.
Il flusso di lavoro di base con URLSession è il seguente: creare una configurazione, creare una sessione basata su di essa, quindi attraverso la sessione creare un'attività con una richiesta URL e avviare l'attività. Esaminiamo un esempio di richiesta GET con una closure. Questo modello è utilizzato nella maggior parte delle applicazioni iOS per recuperare dati da API REST, caricare immagini e interagire con servizi cloud.
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: \(error!.localizedDescription)")
return
}
if let json = try? JSONSerialization.jsonObject(with: data) {
print("JSON: \(json)")
}
}
task.resume()
L'esempio utilizza URLSession.shared — un singleton con configurazione .default per richieste semplici. dataTask crea un'operazione asincrona ma non la avvia — è necessario chiamare resume(). La closure viene eseguita dopo il completamento della richiesta e restituisce data, response o error. Per una sessione personalizzata con la propria configurazione, utilizzare l'inizializzatore URLSession(configuration:), che consente di impostare politiche di cache, timeout, connessioni massime, intestazioni HTTP predefinite e impostazioni proxy per tutte le attività della sessione. Questo approccio offre il controllo completo sul comportamento di rete nell'applicazione.
URLSession supporta il download di file con la possibilità di mettere in pausa e riprendere, oltre ai download in background. DownloadTask salva il file in una directory temporanea e nella closure di completamento è necessario spostarlo in una posizione permanente.
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()
Il parametro location nella closure punta a un file temporaneo che deve essere spostato, altrimenti il sistema lo eliminerà dopo l'uscita dalla closure. Per tracciare l'avanzamento, utilizzare il delegato URLSessionDownloadDelegate con il metodo didWriteData, che passa il numero di byte scritti e la dimensione totale del file — questi dati possono essere utilizzati per visualizzare una barra di avanzamento nell'interfaccia utente. Le sessioni in background con downloadTask consentono di continuare il download anche dopo che l'app è stata ridotta a icona e, al completamento, il sistema chiama il gestore in AppDelegate.
Alamofire è una libreria Swift costruita sopra URLSession che fornisce un'interfaccia più dichiarativa. La scelta tra l'API nativa e Alamofire dipende dalla complessità del progetto e dalle preferenze del team.
| Criterio | URLSession | Alamofire |
|---|---|---|
| Dipendenze | Nessuna, integrato in Foundation | Richiede SPM o CocoaPods |
| Sintassi | Imperativa con closure | Dichiarativa con concatenamento |
| Gestione JSON | JSONSerialization manuale | responseDecodable con Codable |
| Intercettori | Tramite delegati | RequestInterceptor, EventMonitor |
| Avanzamento | Tramite delegato | downloadProgress, uploadProgress |
Per progetti semplici, URLSession è sufficiente e non aggiunge dipendenze. Alamofire è giustificato in progetti con molte richieste di rete, gestione complessa degli errori e necessità di sintassi concisa. Entrambe le tecnologie condividono la base comune URLSessionConfiguration e sono compatibili tra loro. Nella scelta, considerare che URLSession è completamente controllata da Apple e si aggiorna con iOS, mentre Alamofire richiede che gli sviluppatori della libreria mantengano la compatibilità con le nuove versioni del sistema operativo.
Swift moderno supporta async/await, che rende le richieste di rete più leggibili rispetto alle closure. Vediamo la stessa richiesta GET utilizzando la sintassi asincrona.
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
}
Il metodo data(from:) è disponibile da iOS 15 e macOS 12. Restituisce una tupla (Data, URLResponse) e lancia un errore in caso di problemi di rete. JSONDecoder con un modello Codable deserializza automaticamente la risposta — questo sostituisce il complesso JSONSerialization dell'esempio precedente.
Per richieste POST con corpo JSON, si utilizza URLRequest, dove si configurano il metodo, le intestazioni Content-Type e il corpo della richiesta come Data. Async/await rende questo processo conciso e chiaro, e la gestione degli errori è semplice tramite un blocco do-catch.
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)
}
Domande frequenti
URLSession è il moderno sostituto di NSURLConnection, introdotto in iOS 7. Le principali differenze includono il supporto per connessioni multiple attraverso sessioni, sospensione e ripresa delle attività, download in background e WebSocket. NSURLConnection è obsoleto e non è raccomandato per l'uso in nuovi progetti.
Per tracciare l'avanzamento, utilizzare il delegato URLSessionDownloadDelegate con il metodo urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite). In alternativa, per dataTask è possibile sottoscriversi a URLSessionTaskDelegate e ricevere aggiornamenti tramite didSendBodyData.
I download in background vengono configurati tramite la configurazione .background(withIdentifier:). L'app registra un gestore di completamento in AppDelegate e riceve i risultati anche dopo essere stata ridotta a icona o chiusa. Il sistema gestisce il download e notifica l'app tramite il delegato sessionDidFinishEvents.
Sì, da iOS 13, URLSession supporta WebSocket tramite la classe URLSessionWebSocketTask. Viene creata con il metodo webSocketTask(with:) e fornisce i metodi send, receive con supporto per messaggi di testo e binari, oltre a ping/pong per mantenere la connessione attiva.
I timeout vengono configurati tramite URLSessionConfiguration: la proprietà timeoutIntervalForRequest (attesa di risposta a una richiesta) e timeoutIntervalForResource (tempo massimo per l'intero download). Valori predefiniti: 60 secondi per la richiesta e 7 giorni per la risorsa.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche