🏗️ Архитектура приложения

🔌

WebSocket менеджер

// WebSocketManager.swift
class WebSocketManager: ObservableObject {
    @Published var messages: [Message] = []
    private var webSocket: URLSessionWebSocketTask?
    private let serverURL = "wss://client123.example.com/ws"
    
    func connect() {
        guard let url = URL(string: serverURL) else { return }
        webSocket = URLSession.shared.webSocketTask(with: url)
        webSocket?.resume()
        receiveMessage()
    }
    
    private func receiveMessage() {
        webSocket?.receive { [weak self] result in
            switch result {
            case .success(let message):
                self?.handleMessage(message)
                self?.receiveMessage()
            case .failure(let error):
                print("Error: \(error)")
            }
        }
    }
}
🎥

WebRTC клиент

// WebRTCClient.swift
import WebRTC

class WebRTCClient: NSObject {
    private var peerConnection: RTCPeerConnection?
    private let factory = RTCPeerConnectionFactory()
    
    func setupConnection() {
        let config = RTCConfiguration()
        config.iceServers = [RTCIceServer(urlStrings: [
            "stun:stun.l.google.com:19302",
            "turn:turn.example.com:3478"
        ])]
        
        let constraints = RTCMediaConstraints(
            mandatoryConstraints: nil,
            optionalConstraints: ["DtlsSrtpKeyAgreement": "true"]
        )
        
        peerConnection = factory.peerConnection(
            with: config,
            constraints: constraints,
            delegate: self
        )
    }
}
🎨

UI компоненты

// ChatView.swift
import SwiftUI

struct ChatView: View {
    @StateObject private var viewModel = ChatViewModel()
    
    var body: some View {
        VStack {
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 8) {
                    ForEach(viewModel.messages) { message in
                        MessageBubble(message: message)
                    }
                }
                .padding()
            }
            
            HStack {
                TextField("Сообщение...", text: $viewModel.inputText)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                
                Button(action: viewModel.sendMessage) {
                    Image(systemName: "paperplane.fill")
                }
            }
            .padding()
        }
    }
}

✨ Возможности приложения

🔐

Авторизация

Подключение по уникальному коду клиента или ручной ввод URL сервера

🔄

Автоматический выбор

Приложение автоматически пробует подключиться к основному и резервному серверам

📞

WebRTC звонки

Полноценные аудио и видео звонки между пользователями

💬

Текстовый чат

Обмен сообщениями в реальном времени через WebSocket

📱

Нативный UI

Полностью на SwiftUI с поддержкой темной/светлой темы

🔔

Push уведомления

Уведомления о входящих звонках и сообщениях

🛠️ Технологический стек

Swift 5.9 SwiftUI WebRTC WebSocket Combine Xcode 15 iOS 15+ PushKit CallKit