WebSocket in Swift: Real-Time Applications from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why WebSocket is Important for a Swift Developer

Modern mobile and desktop applications increasingly require instant data exchange. Whether it's a chat, a stock trading terminal, an online game, or a push notification system — users expect real-time responses. The WebSocket protocol has become the standard for such tasks, and in the Swift ecosystem (iOS/macOS), its support is implemented natively through URLSessionWebSocketTask.

In this article, we will cover the full cycle of working with WebSocket in Swift: from setting up a connection to creating a full-fledged real-time application. You will learn how to avoid common mistakes, organize reconnection, and integrate WebSocket into the MVVM architecture.



WebSocket Basics in Swift: URLSessionWebSocketTask

Starting with iOS 13 and macOS 10.15, Apple provides a built-in class URLSessionWebSocketTask as part of Foundation. This eliminates the need to use third-party libraries (e.g., Starscream) for basic scenarios.



Creating a WebSocket Connection

To establish a connection, you need to create a URLSession session and set its configuration:

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() }}

Note the waitsForConnectivity — this allows automatic reconnection when the network becomes available.



Sending and Receiving Messages

WebSocket supports two types of messages: text (String) and binary (Data). Let's look at an example of sending:

func sendMessage(_ text: String) {    let message = URLSessionWebSocketTask.Message.string(text)    webSocketTask?.send(message) { error in        if let error = error {            print("Send error: \\(error.localizedDescription)")        }    }}

func sendData(_ data: Data) { let message = URLSessionWebSocketTask.Message.data(data) webSocketTask?.send(message) { error in // error handling }}

For receiving messages, a recursive call to receive is used:

private func receiveMessage() {    webSocketTask?.receive { [weak self] result in        switch result {        case .success(let message):            switch message {            case .string(let text):                print("Received text: \\(text)")            case .data(let data):                print("Received data: \\(data.count) bytes")            @unknown default:                break            }            // Continue listening            self?.receiveMessage()        case .failure(let error):            print("Receive error: \\(error)")        }    }}

Important: the receive call handles only one message. For continuous data reception, it must be called again inside the success closure.



Real-Time Application Architecture in Swift

For production use of WebSocket, the architecture must be carefully designed. It is recommended to use a service layer with a protocol and delegate to separate network logic from the UI.



WebSocket Service Protocol

protocol WebSocketServiceProtocol: AnyObject {    var isConnected: Bool { get }    func connect()    func disconnect()    f                

Blogs

Book Recommendations