WebSocket sur Swift : créer des applications temps réel pour iOS et macOS

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

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                

Blogs

Book Recommendations