- Published on
SwiftUI'da Protocol'lar bilan ishlash (Protocols)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Protokol o'zi nima?
Protokol — bu qoidalar to'plami. Agar biror Klass yoki Struct ushbu protokolga a'zo bo'lsa (conform qilsa), u protokolda aytilgan barcha o'zgaruvchi va funksiyalarni o'zida yozishi shart bo'ladi.
Aslida, siz har kuni protokollardan foydalanasiz. Masalan, har safar yangi ekran yaratganingizda: struct MyView: View { ... } yozasiz. Bu yerdagi View aslida Swift'ning ichki protokoli bo'lib, uning yagona talabi — ichida var body: some View bo'lishi shart!
1. Nega bizga o'zimizning Protokollar kerak?
Aytaylik, ilovamizda Ranglar mavzusi (Color Theme) bor va har bir foydalanuvchi xohlagan rangini tanlashi mumkin:
import SwiftUI
// Default (Asosiy) Ranglar Mavzusi
struct DefaultColorTheme {
let primary: Color = .blue
let secondary: Color = .white
let tertiary: Color = .gray
}
// Boshqa variant
struct AlternativeColorTheme {
let primary: Color = .red
let secondary: Color = .black
let tertiary: Color = .green
}
Endi SwiftUI sahifamizda buni ishlatmoqchimiz:
struct ProtocolsBootcamp: View {
// Agar biz qatiy qilib DefaultColorTheme ni bersak, uni o'zgartirib bo'lmaydi!
let colorTheme: DefaultColorTheme = DefaultColorTheme()
var body: some View {
ZStack {
colorTheme.tertiary.ignoresSafeArea()
Text("Protokollar zo'r!")
.foregroundColor(colorTheme.secondary)
.padding()
.background(colorTheme.primary)
.cornerRadius(10)
}
}
}
Muammo shundaki, biz o'zgaruvchining turini (type) aynan DefaultColorTheme deb berdik. Agar AlternativeColorTheme ga o'zgartirmoqchi bo'lsak, xatolik beradi. Chunki ular ikkita butunlay boshqa-boshqa Struct'lar! Swift ularning ikkalasi ham rang ekanligini bilmaydi.
2. Yechim: Protokol yaratamiz
Ushbu muammoni hal qilish uchun umumiy bir qoida (Protokol) yozamiz:
protocol ColorThemeProtocol {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
Eslatma: Protokollarda let ishlata olmaymiz. Uning o'rniga var yozamiz va oxiriga o'qish uchun { get } yoki o'zgartirish ham mumkin bo'lsa { get set } yozib qo'yamiz.
Endi ranglar mavzumizni ushbu protokolga bo'ysundiramiz:
struct DefaultColorTheme: ColorThemeProtocol {
let primary: Color = .blue
let secondary: Color = .white
let tertiary: Color = .gray
}
struct AlternativeColorTheme: ColorThemeProtocol {
let primary: Color = .red
let secondary: Color = .black
let tertiary: Color = .green
}
3. Protokolni View ichida ishlatish
Endi biz View ichidagi colorTheme ni bemalol o'zgartira olamiz. Chunki biz uning turi ColorThemeProtocol deymiz. Ya'ni u shartlarga javob beradigan ixtiyoriy Struct bo'lishi mumkin:
struct ProtocolsBootcamp: View {
// Diqqat! Turi Protocol nomi qilib belgilandi
let colorTheme: ColorThemeProtocol
var body: some View {
ZStack {
colorTheme.tertiary.ignoresSafeArea()
Text("Protokollar orqali almashinuv!")
.foregroundColor(colorTheme.secondary)
.padding()
.background(colorTheme.primary)
.cornerRadius(10)
}
}
}
// Ishlatish jarayonida xohlagan mavzuni berib yuborish mumkin:
struct ProtocolsBootcamp_Previews: PreviewProvider {
static var previews: some View {
ProtocolsBootcamp(colorTheme: AlternativeColorTheme())
// yoki
// ProtocolsBootcamp(colorTheme: DefaultColorTheme())
}
}
4. Boshqa imkoniyatlari
Protokollar nafaqat o'zgaruvchilarni, balki funksiyalarni ham talab qilishi mumkin. Shuningdek, bitta protokol boshqa protokollarni o'z ichiga olishi mumkin (Protokollar merosxo'rligi):
protocol ButtonTextProtocol {
var buttonText: String { get }
}
protocol ButtonPressedProtocol {
func buttonPressed()
}
// Ikkala qoidani o'zida jamlagan super-protokol
protocol ButtonDataSourceProtocol: ButtonTextProtocol, ButtonPressedProtocol {
// Qolgan qo'shimcha talablar...
}
Xulosa: Protokollar katta ilovalar (Dependency Injection, Testing) yaratishda eng kerakli vosita hisoblanadi. Ular yordamida har xil sinflarni (Classes / Structs) osongina bir-birining o'rniga almashtirib ishlatish mumkin.