WebSocket in Swift: Creating Advanced Level Real-Time Applications
\nIn modern mobile development, real-time interaction has become not just a feature, but a necessity. Financial quotes, online games, messengers, collaborative document editing — all of this requires instant data transfer between the client and server. In the Apple ecosystem, the Swift and Foundation frameworks provide powerful tools for working with the WebSocket protocol. In this article, we will look at advanced techniques: from native URLSessionWebSocketTask to custom error handling, multithreading, and performance optimization.
1. Native WebSocket Implementation via URLSessionWebSocketTask (iOS 13+)
\nStarting with iOS 13, Apple provides built-in WebSocket support through URLSessionWebSocketTask. This is the preferred method as it does not require third-party dependencies and is deeply integrated with the connection management system.
1.1. Creating and Configuring a Session
\nFirst, let's create a WebSocket manager with support for reconnection and thread pooling:
\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. Advanced Message Handling with Typing
\nLet's create an enum for message types and implement 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 // Automatic reconnection after 5 seconds\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() // Cyclic reception\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. Advanced Work with Multithreading and Performance
\nReal-time applications require high performance. Let's look at key optimizations.
\n\n2.1. Thread-Safe Message Queue
\nclass ThreadSafeMessageQueue {\n private var queue = [WebSocketMessage]()\n