WebSocket em Swift: criação de aplicações real-time de nível avançado
\nNo desenvolvimento mobile moderno, a interação real-time tornou-se não apenas um diferencial, mas uma necessidade. Cotações financeiras, jogos online, mensageiros, edição colaborativa de documentos — tudo isso exige transmissão instantânea de dados entre cliente e servidor. No ecossistema Apple, os frameworks Swift e Foundation fornecem ferramentas poderosas para trabalhar com o protocolo WebSocket. Neste artigo, abordaremos técnicas avançadas: desde o nativo URLSessionWebSocketTask até tratamento personalizado de erros, multithreading e otimização de desempenho.
1. Implementação nativa de WebSocket via URLSessionWebSocketTask (iOS 13+)
\nA partir do iOS 13, a Apple oferece suporte integrado a WebSocket através do URLSessionWebSocketTask. Esta é a forma preferida, pois não requer dependências de terceiros e está profundamente integrada ao sistema de gerenciamento de conexões.
1.1. Criação e configuração da sessão
\nPara começar, criaremos um gerenciador WebSocket com suporte a reconexão e pooling de threads:
\nimport Foundation\n\nclass WebSocketManager: NSObject {\n private var webSocketTask: URLSessionWebSocketTask?\n private var session: URLSession!\n private let queue = DispatchQueue(label: "com.websocket.queue", qos: .userInitiated)\n private var isConnected = false\n \n override init() {\n super.init()\n let config = URLSessionConfiguration.default\n config.waitsForConnectivity = true\n config.timeoutIntervalForResource = 300\n session = URLSession(configuration: config, delegate: self, delegateQueue: nil)\n }\n \n func connect(url: URL) {\n webSocketTask = session.webSocketTask(with: url)\n webSocketTask?.resume()\n receiveMessage()\n }\n \n func disconnect() {\n webSocketTask?.cancel(with: .normalClosure, reason: nil)\n isConnected = false\n }\n}\n\n1.2. Tratamento avançado de mensagens com tipagem
\nCriaremos um enum para tipos de mensagens e implementaremos o parsing:
\nenum WebSocketMessage {\n case text(String)\n case data(Data)\n case ping\n case pong\n case error(Error)\n}\n\nextension WebSocketManager: URLSessionWebSocketDelegate {\n func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {\n isConnected = true\n print("WebSocket connected")\n }\n \n func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {\n isConnected = false\n print("WebSocket closed: \\(closeCode)")\n // Reconexão automática após 5 segundos\n DispatchQueue.global().asyncAfter(deadline: .now() + 5) { [weak self] in\n self?.reconnect()\n }\n }\n \n private func receiveMessage() {\n webSocketTask?.receive { [weak self] result in\n switch result {\n case .success(let message):\n self?.handleMessage(message)\n self?.receiveMessage() // Recebimento cíclico\n case .failure(let error):\n self?.handleError(error)\n }\n }\n }\n \n private func handleMessage(_ message: URLSessionWebSocketTask.Message) {\n switch message {\n case .string(let text):\n processText(text)\n case .data(let data):\n processData(data)\n @unknown default:\n break\n }\n }\n}\n\n2. Trabalho avançado com multithreading e desempenho
\nAplicações real-time exigem alto desempenho. Vejamos as principais otimizações.
\n\n2.1. Fila de mensagens thread-safe
\nclass ThreadSafeMessageQueue {\n private var queue = [WebSocketMessage]()\n