Introdução: Por que o WebSocket é importante para o desenvolvedor Swift
\nAplicativos móveis e desktop modernos exigem cada vez mais troca instantânea de dados. Seja um chat, terminal de ações, jogo online ou sistema de notificações push — os usuários esperam reação em tempo real. O protocolo WebSocket tornou-se o padrão para essas tarefas, e no ecossistema Swift (iOS/macOS) seu suporte é implementado nativamente através do URLSessionWebSocketTask.
Neste artigo, abordaremos o ciclo completo de trabalho com WebSocket em Swift: desde a configuração da conexão até a criação de uma aplicação completa em tempo real. Você aprenderá como evitar erros típicos, organizar a reconexão e integrar o WebSocket na arquitetura MVVM.
\n\nFundamentos do WebSocket em Swift: URLSessionWebSocketTask
\nA partir do iOS 13 e macOS 10.15, a Apple fornece a classe nativa URLSessionWebSocketTask como parte do Foundation. Isso elimina a necessidade de bibliotecas de terceiros (como Starscream) para cenários básicos.
Criando uma conexão WebSocket
\nPara estabelecer a conexão, é necessário criar uma sessão URLSession e definir a configuração:
import Foundation\n\nclass WebSocketManager {\n private var webSocketTask: URLSessionWebSocketTask?\n private let session: URLSession\n \n init() {\n let config = URLSessionConfiguration.default\n config.timeoutIntervalForRequest = 30\n config.waitsForConnectivity = true\n session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())\n }\n \n func connect() {\n guard let url = URL(string: "wss://echo.websocket.org") else { return }\n webSocketTask = session.webSocketTask(with: url)\n webSocketTask?.resume()\n receiveMessage()\n }\n}\nObserve o waitsForConnectivity — isso permite restaurar automaticamente a conexão quando a rede estiver disponível.
Envio e recebimento de mensagens
\nO WebSocket suporta dois tipos de mensagens: texto (String) e binário (Data). Vejamos um exemplo de envio:
\nfunc sendMessage(_ text: String) {\n let message = URLSessionWebSocketTask.Message.string(text)\n webSocketTask?.send(message) { error in\n if let error = error {\n print("Erro ao enviar: \\(error.localizedDescription)")\n }\n }\n}\n\nfunc sendData(_ data: Data) {\n let message = URLSessionWebSocketTask.Message.data(data)\n webSocketTask?.send(message) { error in\n // tratamento de erro\n }\n}\nPara receber mensagens, usa-se a chamada recursiva receive:
private func receiveMessage() {\n webSocketTask?.receive { [weak self] result in\n switch result {\n case .success(let message):\n switch message {\n case .string(let text):\n print("Texto recebido: \\(text)")\n case .data(let data):\n print("Dados recebidos: \\(data.count) bytes")\n @unknown default:\n break\n }\n // Continua ouvindo\n self?.receiveMessage()\n case .failure(let error):\n print("Erro ao receber: \\(error)")\n }\n }\n}\nImportante: a chamada receive processa apenas uma mensagem. Para recebimento contínuo de dados, é necessário chamá-la novamente dentro do bloco de sucesso.
Arquitetura de aplicação em tempo real em Swift
\nPara uso em produção com WebSocket, é necessário planejar a arquitetura. Recomenda-se usar uma camada de serviço com protocolo e delegate, para separar a lógica de rede da UI.
\n\nProtocolo do serviço WebSocket
\nprotocol WebSocketServiceProtocol: AnyObject {\n var isConnected: Bool { get }\n func connect()\n func disconnect()\n f