WebSocket in Swift: Echtzeit für iOS und macOS

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einführung in WebSocket mit Swift: Von der Theorie zur fortgeschrittenen Praxis

In der modernen mobilen Entwicklung ist die Echtzeit-Interaktion nicht nur ein Gimmick, sondern eine Notwendigkeit geworden. Benutzer erwarten, dass Chats, Newsfeeds, Kurse und Benachrichtigungen sofort aktualisiert werden, ohne unnötige Pull-to-Refresh-Gesten. WebSocket ist das Protokoll, das eine permanente bidirektionale Verbindung zwischen dem Client (Ihrer Swift-App) und dem Server herstellt.

In diesem Artikel gehen wir über das einfache "Hello, World!" hinaus und behandeln fortgeschrittene Techniken für die Arbeit mit WebSocket in Swift für die Plattformen iOS und macOS. Sie erfahren, wie Sie eine zuverlässige Verbindung einrichten, komplexe Szenarien (Verbindungsabbruch, Wiederverbindung, Hintergrundmodus) verarbeiten und eine Architektur aufbauen, die der Last einer echten Börsen-App oder eines Chats mit Tausenden von Benutzern standhält.

Wir betrachten sowohl den nativen URLSessionWebSocketTask (iOS 13+) als auch die beliebte Bibliothek Starscream für ältere Versionen. Der Code ist voll funktionsfähig und bereit für die Integration.



1. Fortgeschrittene Konfiguration eines WebSocket-Clients in Swift

Beginnen wir mit den Grundlagen. Anstatt einer trivialen Verbindung erstellen wir einen Manager, der den Lebenszyklus der Verbindung verwaltet, Fehler behandelt und Reconnect (automatische Wiederverbindung) unterstützt.



1.1. Manager mit automatischer Wiederverbindung (Reconnect)

Wir implementieren die Klasse WebSocketManager, die URLSessionWebSocketTask verwendet. Das Hauptmerkmal ist eine exponentielle Verzögerung zwischen den Wiederverbindungsversuchen, um den Server nicht zu überlasten.



import Foundation

final class WebSocketManager: NSObject { private var webSocketTask: URLSessionWebSocketTask? private var session: URLSession? private var isConnected = false private var reconnectAttempt = 0 private let maxReconnectDelay: TimeInterval = 30 // Maximale Verzögerung 30 Sek private let baseDelay: TimeInterval = 2 // Basisverzögerung 2 Sek var onMessageReceived: ((String) -> Void)? var onConnectionStateChanged: ((Bool) -> Void)? func connect(url: URL) { session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue()) let request = URLRequest(url: url, timeoutInterval: 10) webSocketTask = session?.webSocketTask(with: request) webSocketTask?.resume() receiveMessage() } private func reconnect() { guard let url = webSocketTask?.originalRequest?.url else { return } let delay = min(baseDelay * pow(2.0, Double(reconnectAttempt)), maxReconnectDelay) print("Reconnecting in \\(delay) seconds... (Attempt \\(reconnectAttempt + 1))") DispatchQueue.global().asyncAfter(deadline: .now() + delay) { [weak self] in self?.connect(url: url) self?.reconnectAttempt += 1 } } private func receiveMessage() { webSocketTask?.receive { [weak self] result in switch result { case .success(let message): switch message { case .string(let text): self?.onMessageReceived?(text) case .data(let data): if let text = String(data: data, encoding: .utf8) { self?.onMessageReceived?(text) } @unknown default: break } self?.reconnectAttempt = 0 // Zurücksetzen des Zählers bei erfolgreichem Empfang self?.receiveMessage() // Weiterhören case .failure(let error): print("Receive error: \\(error.localizedDescription)") self?.disconnect() self?.reconnect() } } } func send(text: String) {

Blogs

Buchempfehlungen