Published on

Yuklash holatlarini modellash

Authors

Tarmoq so'rovi faqat ikkita holatda bo'lmaydi — yuklash va tamom. Haqiqiy ilova kamida to'rtta holat boshqarishi kerak: yuklanmoqda (so'rov davom etayapti), yuklangan (ma'lumot keldi), bo'sh (ma'lumot yo'q) va xato (nimadir noto'g'ri ketdi).

Bu holatlarni enum bilan modellash ishlamaydi deb qo'rqib turgan holatlarni bartaraf etadi.

Holatlar uchun enum

enum YuklamaHolati {
    case yuklanmoqda
    case yuklangan([Post])
    case bosh
    case xato(String)
}

isLoading: Bool + errorMessage: String? + posts: [Post] ishlatish oddiy ko'rinadi, lekin imkonsiz holatlar yaratadi — masalan, isLoading = true va posts = [...] bir vaqtda bo'lishi. Enum bilan bunday noto'g'ri holat mumkin emas.

import SwiftUI

struct Post: Codable, Identifiable {
    let id: Int
    let title: String
    let body: String
}

// Barcha mumkin bo'lgan UI holatlarini belgilaydi
enum YuklamaHolati {
    case yuklanmoqda
    case yuklangan([Post])      // Bog'liq qiymat — ma'lumot holat bilan sayohat qiladi
    case bosh
    case xato(String)           // Bog'liq qiymat — xato xabari
}

struct PostListView: View {
    // Yuklanmoqda bilan boshlash — so'rovdan oldin spinner darhol ko'rinadi
    @State private var holat: YuklamaHolati = .yuklanmoqda

    var body: some View {
        // switch qamrovi to'liq — kompilyator barcha holatni qamrab olishga majbur qiladi
        switch holat {
        case .yuklanmoqda:
            ProgressView("Yuklanmoqda...")
                .progressViewStyle(.circular)

        case .yuklangan(let posts):
            List(posts) { post in
                VStack(alignment: .leading) {
                    Text(post.title).font(.headline)
                    Text(post.body).font(.subheadline).foregroundStyle(.secondary)
                }
            }

        case .bosh:
            ContentUnavailableView("Postlar yo'q", systemImage: "tray")

        case .xato(let xabar):
            VStack(spacing: 16) {
                ContentUnavailableView(
                    "Xato",
                    systemImage: "exclamationmark.triangle",
                    description: Text(xabar)
                )
                // Qayta urinish tugmasi — Task async kontekst yaratadi
                Button("Qayta urinish") {
                    Task { await postlarniOl() }
                }
                .buttonStyle(.borderedProminent)
            }
        }
    }

    func postlarniOl() async {
        holat = .yuklanmoqda
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else {
            holat = .xato("Noto'g'ri URL")
            return
        }
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            let decoded = try JSONDecoder().decode([Post].self, from: data)
            await MainActor.run {
                holat = decoded.isEmpty ? .bosh : .yuklangan(decoded)
            }
        } catch {
            await MainActor.run {
                holat = .xato(error.localizedDescription)
            }
        }
    }
}
QatorVazifasi
enum YuklamaHolatiBarcha mumkin bo'lgan holatlarni belgilaydi. yuklangan holati bog'liq qiymatga ega — postlar massivini olib yuradi.
case yuklangan([Post])Bog'liq qiymatli enum holat. holat = .yuklangan(posts) o'rnatganda ma'lumot holat o'zgarishi bilan sayohat qiladi. Switch da let posts bilan ajratib olinadi.
@State private var holat: YuklamaHolati = .yuklanmoqdaBirinchi renderda spinner darhol ko'rinishi uchun yuklanmoqda holatida boshlanadi.
switch holat { }Swift ning enum bo'yicha switch to'liq qamrovli — kompilyator barcha holatni qamrab olishga majbur qiladi.
ContentUnavailableViewBo'sh va xato holatlari uchun o'rnatilgan SwiftUI View (iOS 17+). Apple dizayn konventsiyalarini avtomatik kuzatadi.

Yuklama holati patternlari

// ProgressView — yuklash paytida spinner
case .yuklanmoqda:
    ProgressView("Ma'lumot olinmoqda...")
        .progressViewStyle(.circular)
// Skelet — yuklash paytida placeholder kontent
case .yuklanmoqda:
    List(0..<5, id: \.self) { _ in
        Text("Placeholder post sarlavhasi")
    }
    .redacted(reason: .placeholder)
// Qayta urinish tugmasi — xato holatida
case .xato(let xabar):
    VStack(spacing: 16) {
        Text(xabar).foregroundStyle(.secondary)
        Button("Qayta urinish") {
            Task { await postlarniOl() }
        }
        .buttonStyle(.borderedProminent)
    }

Tezkor ma'lumotnoma

SintaksisVazifasi
enum YuklamaHolatiTarmoq operatsiyasi uchun barcha mumkin UI holatlarini belgilaydi
case yuklangan([Post])Bog'liq qiymatli enum holat — ma'lumot holat bilan sayohat qiladi
switch holat { case .yuklangan(let posts): }To'liq qamrovli switch — kompilyator barcha holatni qamrab olishga majbur qiladi
ProgressView("Yuklanmoqda...")Ixtiyoriy belgi bilan aylana spinner ko'rsatadi
.redacted(reason: .placeholder)Kontent yuklash paytida kulrang skelet shakllar bilan almashtiradi
ContentUnavailableViewBo'sh va xato holatlari uchun tizim ko'rinishi (iOS 17+)
Task { await ... }Sinxron kontekstdan (masalan Button action) asinxron vazifa yaratadi

🎯 Topshiriq: to'rtta holatni boshqarish

8.2 darsdan PostListView ni YuklamaHolati enum ishlatishga qayta yozing. Enumingizda to'rtta holat bo'lsin: yuklanmoqda, yuklangan([Post]), bosh va xato(String). Yuklash paytida ProgressView, yuklanganda List, bo'sh va xato holatlarida ContentUnavailableView ko'rsating. Xato holatini sinab ko'rish uchun URLni vaqtincha noto'g'ri qilib, xato holati to'g'ri ko'rinishini tasdiqlang.

Buy mea coffee