Published on

SwiftUI Advanced: Custom Errors va Alerts (Maxsus xatoliklar va ogohlantirishlar)

Authors

Xatolik (Error) va Ogohlantirish (Alert) o'rtasidagi farq

Ko'p dasturchilar "Error" va "Alert" so'zlarini sinonim sifatida ishlatishadi. Ammo arxitektura jihatidan ular boshqa-boshqa narsalar:

  • Error (Xatolik): Kod ichida (masalan, tarmoqqa ulanishda) aylanib yuradigan ob'ekt. Foydalanuvchiga to'g'ridan-to'g'ri ko'rsatilmaydi.
  • Alert (Ogohlantirish): O'sha xatolik yuz berganda ekranga chiquvchi UI (oynacha). U o'zida sarlavha, matn va tugmalarni saqlaydi.

Yaxshi yozilgan dasturda Error'lar ushlanib, foydalanuvchiga chiroyli Alert qilib ko'rsatiladi.

1. Custom error (Maxsus xatolik) yaratish

Swift'da o'z xatoligingizni yaratish uchun oddiy Enum dan foydalanasiz. Ammo unga foydalanuvchi tushunadigan matn berish uchun LocalizedError protokolidan foydalanish kerak.

import Foundation

enum MyCustomError: Error, LocalizedError {
    case noInternet
    case dataNotFound
    case urlError(error: Error) // Haqiqiy tizim xatosini ham ichida saqlashi mumkin

    // Foydalanuvchiga ko'rinadigan matn
    var errorDescription: String? {
        switch self {
        case .noInternet:
            return "Internetga ulanish yo'q. Iltimos, ulanishni tekshiring."
        case .dataNotFound:
            return "Ma'lumot topilmadi. Qaytadan urinib ko'ring."
        case .urlError(let error):
            return "Xatolik yuz berdi: \(error.localizedDescription)"
        }
    }
}

Bu usul bilan kodning qayeridadir throw MyCustomError.noInternet desangiz, darhol toza va tushunarli matn qaytadi.

2. Maxsus Alert arxitekturasi

Ekranga chiqadigan Alert nafaqat sarlavha (title), balki qo'shimcha matn (subtitle) va tugmalarga (buttons) ham ega. Buni umumlashtirish uchun bitta Protokol yaratamiz:

import SwiftUI

protocol AppAlert {
    var title: String { get }
    var subtitle: String? { get }
    var buttons: AnyView { get } // AnyView - har qanday turdagi View ni qabul qiladi
}

Endi shu protokolga mos keladigan o'zimizning Alert Enum'imizni yozamiz:

enum MyCustomAlert: AppAlert {
    case noInternet
    case dataNotFound

    var title: String {
        switch self {
        case .noInternet: return "Internet xatosi"
        case .dataNotFound: return "Ma'lumot xatosi"
        }
    }

    var subtitle: String? {
        switch self {
        case .noInternet: return "Tarmoqqa ulanib bo'lmadi."
        case .dataNotFound: return nil
        }
    }

    var buttons: AnyView {
        AnyView(getButtonsForAlert)
    }

    @ViewBuilder
    private var getButtonsForAlert: some View {
        switch self {
        case .noInternet:
            Button("OK") { }
        case .dataNotFound:
            Button("Qayta urinish") {
                // Qayta urinish kodi
            }
            Button("Bekor qilish", role: .cancel) { }
        }
    }
}

3. View uchun qulay Extension (ViewModifier)

Endi har safar Alert chaqirganda kodingiz uzun bo'lib ketmasligi uchun View ga qulay kengaytma yozamiz (bu yerda oldingi darsda o'rgangan Custom Binding yordam beradi!):

extension View {
    func showCustomAlert<T: AppAlert>(alert: Binding<T?>) -> some View {
        self.alert(
            alert.wrappedValue?.title ?? "Xatolik",
            isPresented: Binding(
                get: { alert.wrappedValue != nil },
                set: { newValue in
                    if !newValue { alert.wrappedValue = nil }
                }
            ),
            presenting: alert.wrappedValue
        ) { alertDetails in
            alertDetails.buttons
        } message: { alertDetails in
            if let subtitle = alertDetails.subtitle {
                Text(subtitle)
            }
        }
    }
}

Natija qanday bo'ldi?

Barcha sozlamalar tayyor bo'lgach, endi SwiftUI sahifangizda kod shunchaki ajoyib ko'rinadi:

struct ErrorAlertBootcamp: View {
    // Faqat bitta @State kerak
    @State private var alert: MyCustomAlert? = nil

    var body: some View {
        Button("Xatoni ko'rsatish") {
            alert = .dataNotFound
        }
        // Faqat bitta qator orqali istalgan alertni chaqiramiz!
        .showCustomAlert(alert: $alert)
    }
}

Shu arxitektura yordamida ilovadagi yuzlab xatoliklarni bitta qator kod bilan, juda toza ko'rinishda boshqara olasiz. Hech qanday chalkashlik, ortiqcha Boolean'lar va qiyin logikalar qolmadi!

Buy mea coffee