- Published on
SwiftUI Advanced: Custom Errors va Alerts (Maxsus xatoliklar va ogohlantirishlar)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
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!