Introducción: por qué WebSocket es importante para el desarrollador de Swift
En el desarrollo moderno de aplicaciones móviles y de escritorio, los usuarios están acostumbrados a actualizaciones instantáneas: el feed de noticias se actualiza sin recargar, el estado del interlocutor en el chat cambia en tiempo real, y las cotizaciones bursátiles llegan con retrasos de milisegundos. El HTTP tradicional con su modelo de solicitud-respuesta no es eficiente para estas tareas: crea una carga excesiva en el servidor y en la batería del dispositivo.
El protocolo WebSocket viene al rescate. Establece una conexión bidireccional permanente entre el cliente (aplicación iOS/macOS en Swift) y el servidor. En este artículo, analizaremos dos formas principales de trabajar con WebSocket en Swift: la nativa URLSessionWebSocketTask (iOS 13+ / macOS 10.15+) y la popular biblioteca de terceros Starscream. Aprenderá cómo crear un chat en tiempo real, configurar la reconexión automática y manejar errores.
Fundamentos de WebSocket en Swift: URLSessionWebSocketTask
A partir de iOS 13 y macOS Catalina, Apple proporcionó soporte integrado para WebSocket a través de la clase URLSessionWebSocketTask. Esta es una forma simple y segura que no requiere instalar dependencias adicionales.
Creación y configuración de la conexión
Para empezar, crearemos una instancia de URLSession y configuraremos sus parámetros. Tenga en cuenta: para trabajar con WebSocket, debe usar el protocolo wss:// (conexión segura) o ws:// (no segura, solo para desarrollo).
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("Conexión WebSocket establecida") receiveMessage() }}Envío y recepción de mensajes
WebSocket admite dos tipos de mensajes: de cadena (String) y binarios (Data). Veamos el envío:
func sendMessage(_ text: String) { let message = URLSessionWebSocketTask.Message.string(text) webSocketTask?.send(message) { error in if let error = error { print("Error al enviar: \\(error.localizedDescription)") } else { print("Mensaje enviado: \\(text)") } }}Para recibir mensajes, es necesario implementar una llamada recursiva al método receive:
private func receiveMessage() { webSocketTask?.receive { [weak self] result in switch result { case .success(let message): switch message { case .string(let text): print("Mensaje de texto recibido: \\(text)") case .data(let data): print("Datos binarios recibidos: \\(data.count) bytes") @unknown default: break } // Continuamos escuchando los siguientes mensajes self?.receiveMessage() case .failure(let error): print("Error al recibir: \\(error.localizedDescription)") // Aquí se puede implementar la reconexión } }}Cierre de la conexión y manejo de errores
El cierre correcto del trabajo con WebSocket es una parte importante de una aplicación en producción:
func disconnect() { let closeCode = URLSessionWebSocketTask.CloseCode.normalClosure webSocketTask?.cancel(with: closeCode, reason: nil) p