引言:为什么 WebSocket 对 Swift 开发者很重要
现代移动和桌面应用越来越需要即时数据交换。无论是聊天、股票交易终端、在线游戏还是推送通知系统——用户都期望实时响应。WebSocket 协议已成为此类任务的标准,而在 Swift(iOS/macOS)生态系统中,其支持通过 URLSessionWebSocketTask 原生实现。
在本文中,我们将介绍在 Swift 中使用 WebSocket 的完整流程:从建立连接到创建完整的实时应用。您将学习如何避免常见错误、组织重连以及将 WebSocket 集成到 MVVM 架构中。
Swift 中的 WebSocket 基础:URLSessionWebSocketTask
从 iOS 13 和 macOS 10.15 开始,Apple 在 Foundation 中提供了内置类 URLSessionWebSocketTask。这省去了在基本场景中引入第三方库(例如 Starscream)的必要。
创建 WebSocket 连接
要建立连接,需要创建一个 URLSession 会话并设置配置:
import Foundation
class WebSocketManager { private var webSocketTask: URLSessionWebSocketTask? private let session: URLSession init() { let config = URLSessionConfiguration.default config.timeoutIntervalForRequest = 30 config.waitsForConnectivity = true session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue()) } func connect() { guard let url = URL(string: "wss://echo.websocket.org") else { return } webSocketTask = session.webSocketTask(with: url) webSocketTask?.resume() receiveMessage() }}请注意 waitsForConnectivity——这允许在网络可用时自动恢复连接。
发送和接收消息
WebSocket 支持两种消息类型:文本(String)和二进制(Data)。我们来看一个发送示例:
func sendMessage(_ text: String) { let message = URLSessionWebSocketTask.Message.string(text) webSocketTask?.send(message) { error in if let error = error { print("发送错误:\\(error.localizedDescription)") } }}
func sendData(_ data: Data) { let message = URLSessionWebSocketTask.Message.data(data) webSocketTask?.send(message) { error in // 错误处理 }}接收消息使用递归调用 receive:
private func receiveMessage() { webSocketTask?.receive { [weak self] result in switch result { case .success(let message): switch message { case .string(let text): print("收到文本:\\(text)") case .data(let data): print("收到数据:\\(data.count) 字节") @unknown default: break } // 继续监听 self?.receiveMessage() case .failure(let error): print("接收错误:\\(error)") } }}重要提示:receive 调用只处理一条消息。为了持续接收数据,需要在成功闭包内重复调用它。
Swift 实时应用的架构
对于生产环境中的 WebSocket 使用,需要精心设计架构。建议使用带有协议和委托的服务层,以将网络逻辑与 UI 分离。
WebSocket 服务协议
protocol WebSocketServiceProtocol: AnyObject { var isConnected: Bool { get } func connect() func disconnect() f