- Published on
Swift-da Codable, Decodable va Encodable protokollari
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Bu video keyingi videolar uchun tayyorlov — internetdan ma'lumot yuklab, ilovada ishlatish. Internetdan kelgan ma'lumot bevosita ishlatib bo'lmaydi — avval decode qilish kerak. Bu videoda qo'lda decode qilishdan boshlab, Codable protokoligacha bosqichma-bosqich ko'rib chiqiladi.
Boshlang'ich model va ViewModel
struct CustomerModel: Identifiable {
let id: String
let name: String
let points: Int
let isPremium: Bool
}
class CodableViewModel: ObservableObject {
@Published var customer: CustomerModel? = nil
init() {
getData()
}
func getData() { }
}
JSON data nima?
Internetdan kelgan ma'lumot odatda JSON formatida bo'ladi. JSON — matn ko'rinishidagi ma'lumot. Masalan:
{"id":"12345","name":"Joe","points":5,"isPremium":true}
Bu ilovaga Data (baytlar) sifatida keladi. Ularni to'g'ridan-to'g'ri ekranda ko'rsatib bo'lmaydi — avval CustomerModel-ga aylantirish kerak.
Soxta JSON data yaratish (test uchun)
Haqiqiy internet yuklamasi o'rniga, qanday ko'rinishini ko'rsatish uchun soxta JSON:
func getJsonData() -> Data? {
let dictionary: [String: Any] = [
"id": "12345",
"name": "Joe",
"points": 5,
"isPremium": true
]
return try? JSONSerialization.data(withJSONObject: dictionary, options: [])
}
1-bosqich: Qo'lda decode qilish (Codable-siz)
func getData() {
guard let data = getJsonData() else { return }
// Data → local object
guard let localData = try? JSONSerialization.jsonObject(with: data, options: []),
let dictionary = localData as? [String: Any],
let id = dictionary["id"] as? String,
let name = dictionary["name"] as? String,
let points = dictionary["points"] as? Int,
let isPremium = dictionary["isPremium"] as? Bool
else { return }
let newCustomer = CustomerModel(
id: id,
name: name,
points: points,
isPremium: isPremium
)
self.customer = newCustomer
}
Bu ishlaydi, lekin muammo bor: har bir o'zgaruvchini qo'lda yozish kerak. Model 20 ta xususiyat bo'lsa — 20 ta satr. Har safar xususiyat qo'shilganda — decode-ni ham yangilash kerak.
2-bosqich: Decodable protokoli
Decodable — modelni JSON-dan avtomatik yaratish imkonini beradi. Buning uchun ikkita narsa kerak:
1. CodingKeys — kalitlarni belgilash
struct CustomerModel: Identifiable, Decodable {
let id: String
let name: String
let points: Int
let isPremium: Bool
// JSON kalit nomlari
enum CodingKeys: String, CodingKey {
case id
case name
case points
case isPremium
// JSON-da "isPremium" deb kelsa — shu nomlar mos kelishi shart
}
// Agar JSON-da boshqa nom bo'lsa, raw value bilan moslash:
// case isPremium = "is_premium" // JSON-da "is_premium" deb kelsa
}
2. init(from decoder:) — decode initsializatori
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Har bir xususiyatni tur bilan decode qilish
self.id = try container.decode(String.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
self.points = try container.decode(Int.self, forKey: .points)
self.isPremium = try container.decode(Bool.self, forKey: .isPremium)
}
JSONDecoder bilan bir qatorli foydalanish
func getData() {
guard let data = getJsonData() else { return }
// Barcha manual decode o'rniga — bitta qator
self.customer = try? JSONDecoder().decode(CustomerModel.self, from: data)
}
3-bosqich: Encodable protokoli
Encodable — aksincha: modelni JSON data-ga aylantirish. Server-ga ma'lumot yuborish kerak bo'lganda ishlatiladi.
struct CustomerModel: Identifiable, Decodable, Encodable {
// ...
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(points, forKey: .points)
try container.encode(isPremium, forKey: .isPremium)
}
}
JSONEncoder bilan foydalanish
// Dictionary → JSON Data o'rniga
let customer = CustomerModel(id: "111", name: "Emily", points: 100, isPremium: false)
let jsonData = try? JSONEncoder().encode(customer)
// Bu jsonData endi serverga yuborish uchun tayyor
4-bosqich: Codable = Decodable + Encodable
// Decodable + Encodable = Codable
struct CustomerModel: Identifiable, Codable {
let id: String
let name: String
let points: Int
let isPremium: Bool
}
Codable qo'llanganda, CodingKeys, init(from decoder:) va encode(to encoder:) funksiyalarini yozish shart emas — Swift bularni avtomatik bajaradi.
// Decode — bir qator
let customer = try? JSONDecoder().decode(CustomerModel.self, from: data)
// Encode — bir qator
let jsonData = try? JSONEncoder().encode(customer)
Qachon qo'lda decode kerak?
Codable barcha ishni avtomatik qiladi, lekin ba'zan qo'lda yozish kerak bo'ladi:
// JSON-da kalit nomi Swift-dagi nomdan farq qilsa
enum CodingKeys: String, CodingKey {
case id
case name
case points
case isPremium = "is_premium" // JSON-da "is_premium", model-da isPremium
}
Bu holda faqat CodingKeys yoziladi — init(from:) va encode(to:) esa avtomatik ishlaydi.
Xulosa
JSON Data → Decode → CustomerModel (JSONDecoder)
CustomerModel → Encode → JSON Data (JSONEncoder)
Decodable — decode imkoni (JSON → Model)
Encodable — encode imkoni (Model → JSON)
Codable — ikkalasi (Decodable + Encodable)
| Qo'lda | Decodable/Encodable | Codable | |
|---|---|---|---|
| Kod miqdori | Ko'p | O'rtacha | Minimal |
| Moslashuvchanlik | To'liq | To'liq | Mos kalit nomlar uchun yetarli |
| Tavsiya | Yo'q | Maxsus hollarda | Ko'pincha yetarli |
Keyingi videoda Codable protokolidan foydalanib, haqiqiy API-dan ma'lumot yuklab olamiz.