- Published on
WebSocket va Combine asoslari
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
HTTP β so'rov yuborib javob kutish. Lekin chat, jonli narxlar, o'yin β real-time kerak. WebSocket β doimiy ochiq kanal. Combine β reaktiv ma'lumot oqimi.
WebSocket asoslari
// βββββββββββββββββββββββββββββββββββββββ
// WEBSOCKET β real-time ulanish
// βββββββββββββββββββββββββββββββββββββββ
class WebSocketMenejer: ObservableObject {
@Published var xabarlar: [String] = []
@Published var ulangan = false
private var webSocketTask: URLSessionWebSocketTask?
func ulanish() {
let url = URL(string: "wss://echo.websocket.org")!
webSocketTask = URLSession.shared.webSocketTask(with: url)
webSocketTask?.resume()
ulangan = true
// Xabar qabul qilishni boshlash
qabulQilish()
}
func xabarYuborish(_ matn: String) {
let xabar = URLSessionWebSocketTask.Message.string(matn)
webSocketTask?.send(xabar) { xato in
if let xato {
print("Yuborish xatosi: \(xato)")
}
}
}
private func qabulQilish() {
webSocketTask?.receive { [weak self] natija in
switch natija {
case .success(let xabar):
switch xabar {
case .string(let matn):
DispatchQueue.main.async {
self?.xabarlar.append(matn)
}
case .data(let data):
print("Data: \(data.count) bayt")
@unknown default:
break
}
// Keyingi xabarni kutish
self?.qabulQilish()
case .failure(let xato):
print("Qabul xatosi: \(xato)")
}
}
}
func uzish() {
webSocketTask?.cancel(with: .goingAway, reason: nil)
ulangan = false
}
}
Combine asoslari
import Combine
// βββββββββββββββββββββββββββββββββββββββ
// PUBLISHER VA SUBSCRIBER
// βββββββββββββββββββββββββββββββββββββββ
class HisoblashMisol {
var cancellables = Set<AnyCancellable>()
func boshlash() {
// Publisher β har 1 soniyada raqam chiqaradi
let publisher = Timer.publish(every: 1.0, on: .main, in: .common)
.autoconnect()
.map { _ in Int.random(in: 1...100) } // Tasodifiy son
// Subscriber β qiymatlarni qabul qiladi
publisher
.filter { $0 > 50 } // Faqat 50 dan katta
.map { "Son: \($0)" } // String ga aylantirish
.sink { matn in // Natijani olish
print(matn)
}
.store(in: &cancellables) // Subscription ni saqlash
}
}
// βββββββββββββββββββββββββββββββββββββββ
// @PUBLISHED VA COMBINE
// βββββββββββββββββββββββββββββββββββββββ
class QidiruvViewModel: ObservableObject {
@Published var qidiruvMatni = ""
@Published var natijalar: [String] = []
private var cancellables = Set<AnyCancellable>()
init() {
// $qidiruvMatni β Combine Publisher
$qidiruvMatni
// 0.5 soniya kutish (debounce)
.debounce(for: .seconds(0.5), scheduler: RunLoop.main)
// Bo'sh matnni filtrlash
.filter { !$0.isEmpty }
// Avvalgi qidiruv bilan bir xil bo'lsa o'tkazib yuborish
.removeDuplicates()
// Natijani olish
.sink { [weak self] matn in
self?.qidirish(matn)
}
.store(in: &cancellables)
}
private func qidirish(_ matn: String) {
// Tarmoq so'rovi...
natijalar = ["Natija: \(matn)"]
}
}
Combine Operatorlar
// βββββββββββββββββββββββββββββββββββββββ
// ASOSIY OPERATORLAR
// βββββββββββββββββββββββββββββββββββββββ
// map β qiymatni o'zgartirish
[1, 2, 3].publisher
.map { $0 * 10 } // [10, 20, 30]
// filter β filtrlash
[1, 2, 3, 4, 5].publisher
.filter { $0 > 3 } // [4, 5]
// debounce β kutish (qidiruv uchun)
$matn.debounce(for: .seconds(0.3), scheduler: RunLoop.main)
// throttle β cheklash (scroll uchun)
$matn.throttle(for: .seconds(1), scheduler: RunLoop.main, latest: true)
// combineLatest β ikki publisher ni birlashtirish
$ism.combineLatest($email)
.map { ism, email in
!ism.isEmpty && email.contains("@")
}
.assign(to: &$formaTugri)
// flatMap β ichki publisher ga o'tish
$userId
.flatMap { id in
self.foydalanuvchiYukla(id: id)
}
π― Topshiriq
Chat ilovasi yarating: WebSocket bilan ulanish, xabar yuborish/qabul qilish. Combine bilan $qidiruvMatni ga debounce(0.3) va removeDuplicates qo'llab, "yozmoqda..." indikatorini ko'rsating.