WebSocket библиотеки для Swift (iOS/macOS): Starscream и URLSessionWebSocketTask
WebSocket — это протокол, обеспечивающий постоянное двустороннее соединение между клиентом (iOS/macOS приложением) и сервером. В отличие от HTTP, после установки соединения данные могут передаваться в реальном времени без повторных запросов. Для Swift существует два основных подхода: использование встроенного URLSessionWebSocketTask (доступен с iOS 13/macOS 10.15) и сторонняя библиотека Starscream (поддерживает более старые версии и предоставляет расширенный функционал).
1. URLSessionWebSocketTask — нативный WebSocket в Swift
Начиная с iOS 13 и macOS 10.15, Apple добавила поддержку WebSocket прямо в URLSession. Это означает, что для базовых сценариев не требуется устанавливать дополнительные зависимости.
Пример подключения и отправки сообщения
import Foundation
class WebSocketManager: NSObject {
private var webSocketTask: URLSessionWebSocketTask?
private let session = URLSession(configuration: .default)
func connect() {
guard let url = URL(string: "wss://echo.websocket.org") else { return }
webSocketTask = session.webSocketTask(with: url)
webSocketTask?.resume()
receiveMessage()
}
func sendMessage(_ text: String) {
let message = URLSessionWebSocketTask.Message.string(text)
webSocketTask?.send(message) { error in
if let error = error {
print("Ошибка отправки: \(error.localizedDescription)")
}
}
}
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.localizedDescription)")
}
}
}
func disconnect() {
webSocketTask?.cancel(with: .normalClosure, reason: nil)
}
}
Преимущества URLSessionWebSocketTask
- Без зависимостей — всё уже есть в системе.
- Нативная интеграция с фоновыми задачами и App Transport Security.
- Поддержка Apple и обновления вместе с ОС.
Недостатки
- Минимальная версия iOS 13 / macOS 10.15.
- Отсутствие встроенной поддержки reconnection и ping/pong (нужно реализовывать вручную).
- Меньше гибкости в настройках.
2. Starscream — мощная и гибкая WebSocket библиотека для Swift
Starscream — самая популярная сторонняя WebSocket библиотека для Swift. Она поддерживает iOS 8+, macOS 10.10+, а также watchOS и tvOS. Starscream предоставляет встроенный механизм переподключения, автоматический ping/pong и поддержку SSL/TLS.
Установка через Swift Package Manager
// В Package.swift или через Xcode: File → Add Packages...
// URL: https://github.com/daltoniam/Starscream.git
// Версия: от 4.0.0 и выше
Пример использования Starscream
import Starscream
class StarscreamManager: WebSocketDelegate {
var socket: WebSocket?
func setupConnection() {
var request = URLRequest(url: URL(string: "wss://echo.websocket.org")!)
request.timeoutInterval = 5
socket = WebSocket(request: request)
socket?.delegate = self
socket?.connect()
}
// MARK: - WebSocketDelegate
func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected(let headers):
print("Подключено: \(headers)")
case .disconnected(let reason, let code):
print("Отключено: \(reason) (код \(code))")
case .text(let string):
print("Текст: \(string)")
case .binary(let data):
print("Бинарные данные: \(data)")
case .ping(let data):
print("Ping получен")
case .pong(let data):
print("Pong получен")
case .viabilityChanged(let isViable):
print("Соединение активно: \(isViable)")
case .reconnectSuggested(let shouldReconnect):
if shouldReconnect {
print("Рекомендуется переподключение")
client.connect()
}
case .cancelled:
print("Соединение отменено")
case .error(let error):
print("Ошибка: \(error?.localizedDescription ?? "неизвестная")")
}
}
func sendMessage(_ text: String) {
socket?.write(string: text)
}
func disconnect() {
socket?.disconnect()
}
}
Преимущества Starscream
- Обратная совместимость с iOS 8+.
- Автоматический ping/pong для поддержа