Introduction : pourquoi WebSocket est important pour un développeur Swift
Dans le développement mobile et desktop moderne, les utilisateurs sont habitués aux mises à jour instantanées : le fil d'actualités se met à jour sans rechargement, le statut d'un interlocuteur dans un chat change en temps réel, et les cotations boursières arrivent avec un délai de quelques millisecondes. Le HTTP traditionnel avec son modèle requête-réponse est inefficace pour ces tâches — il crée une charge excessive sur le serveur et la batterie de l'appareil.
Le protocole WebSocket vient à la rescousse. Il établit une connexion permanente bidirectionnelle entre le client (application iOS/macOS en Swift) et le serveur. Dans cet article, nous allons examiner deux méthodes principales pour travailler avec WebSocket en Swift : la solution native URLSessionWebSocketTask (iOS 13+ / macOS 10.15+) et la bibliothèque tierce populaire Starscream. Vous apprendrez à créer un chat en temps réel, à configurer une reconnexion automatique et à gérer les erreurs.
Bases de WebSocket en Swift : URLSessionWebSocketTask
Depuis iOS 13 et macOS Catalina, Apple a fourni un support intégré pour WebSocket via la classe URLSessionWebSocketTask. C'est une méthode simple et sécurisée qui ne nécessite pas l'installation de dépendances supplémentaires.
Création et configuration de la connexion
Pour commencer, créons une instance de URLSession et définissons sa configuration. Notez : pour travailler avec WebSocket, il faut utiliser le protocole wss:// (connexion sécurisée) ou ws:// (non sécurisée, uniquement pour le développement).
import Foundation
class WebSocketManager: NSObject {
private var webSocketTask: URLSessionWebSocketTask?
private let session: URLSession
override init() {
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30
config.waitsForConnectivity = true
self.session = URLSession(configuration: config, delegate: nil, delegateQueue: OperationQueue())
super.init()
}
func connect() {
guard let url = URL(string: "wss://echo.websocket.org") else { return }
webSocketTask = session.webSocketTask(with: url)
webSocketTask?.resume()
print("Connexion WebSocket établie")
receiveMessage()
}
}
Envoi et réception de messages
WebSocket prend en charge deux types de messages : les chaînes (String) et les données binaires (Data). Voyons l'envoi :
func sendMessage(_ text: String) {
let message = URLSessionWebSocketTask.Message.string(text)
webSocketTask?.send(message) { error in
if let error = error {
print("Erreur d'envoi : \\(error.localizedDescription)")
} else {
print("Message envoyé : \\(text)")
}
}
}
Pour recevoir des messages, il faut implémenter un appel récursif de la méthode receive :
private func receiveMessage() {
webSocketTask?.receive { [weak self] result in
switch result {
case .success(let message):
switch message {
case .string(let text):
print("Message texte reçu : \\(text)")
case .data(let data):
print("Données binaires reçues : \\(data.count) octets")
@unknown default:
break
}
// Continuer à écouter les messages suivants
self?.receiveMessage()
case .failure(let error):
print("Erreur de réception : \\(error.localizedDescription)")
// Ici, on peut implémenter la reconnexion
}
}
}
Fermeture de la connexion et gestion des erreurs
Une terminaison correcte du travail avec WebSocket est une partie importante d'une application de production :
func disconnect() {
let closeCode = URLSessionWebSocketTask.CloseCode.normalClosure
webSocketTask?.cancel(with: closeCode, reason: nil)
p