مقدمة: لماذا WebSocket مهم لمطور Swift
تتطلب تطبيقات الهواتف المحمولة وأجهزة الكمبيوتر المكتبية الحديثة بشكل متزايد تبادلاً فورياً للبيانات. سواء كان ذلك محادثة، أو محطة تداول، أو لعبة عبر الإنترنت، أو نظام إشعارات فورية - يتوقع المستخدمون ردود فعل في الوقت الفعلي. أصبح بروتوكول WebSocket معياراً لمثل هذه المهام، وفي نظام Swift البيئي (iOS/macOS) يتم دعمه أصلاً عبر URLSessionWebSocketTask.
في هذه المقالة، سنقوم بتحليل دورة العمل الكاملة مع WebSocket على Swift: من إعداد الاتصال إلى إنشاء تطبيق وقت فعلي متكامل. ستتعلم كيفية تجنب الأخطاء النموذجية، وتنظيم إعادة الاتصال، ودمج WebSocket في بنية MVVM.
أساسيات WebSocket في Swift: URLSessionWebSocketTask
بدءاً من iOS 13 و macOS 10.15، توفر Apple فئة مدمجة URLSessionWebSocketTask ضمن Foundation. وهذا يلغي الحاجة إلى ربط مكتبات خارجية (مثل 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، من الضروري تصميم البنية. يُوصى باستخدام طبقة خدمة مع بروتوكول ومفوض، لفصل منطق الشبكة عن واجهة المستخدم.
بروتوكول خدمة WebSocket
protocol WebSocketServiceProtocol: AnyObject { var isConnected: Bool { get } func connect() func disconnect() f