Published on

Codable bilan JSON dekodlash

Authors

8.2 darsda Codable ni Post strukturasida ishlatdingiz, lekin u aslida nima qilishini chuqur ko'rmadingiz. Ushbu darsda Codable qanday ishlashi, JSON xususiyat nomlari Swift nomlari bilan mos kelmasa nima qilish kerakligi va haqiqiy API larda juda keng tarqalgan ichma-ich JSON tuzilmalarini qanday dekodlash o'rganiladi.

Codable β€” strukturangizga JSON kabi tashqi ma'lumot formatlaridan va unga aylana olish imkoniyatini beradigan Swift protokoli. Strukturangizga Codable qo'shsangiz, Swift encode va decode uchun zarur kodni avtomatik yaratadi. Bu mantiqni o'zingiz yozishingiz shart emas β€” kompilyator buni qiladi.

CodingKeys β€” nomlarni moslashtirish

Avtomatik dekodlash buzilishining eng keng tarqalgan holati β€” JSON xususiyat nomlari Swift xususiyat nomlari bilan mos kelmasa. JSON API lari ko'pincha snake_case (user_name) ishlatadi, Swift konventsiyasi esa camelCase (userName). CodingKeys bu tafovutni ko'piradi.

import SwiftUI

// JSON shunday ko'rinishi mumkin:
// { "user_name": "Ali", "post_count": 42, "is_verified": true }
struct UserProfile: Codable {
    let userName: String
    let postCount: Int
    let isVerified: Bool

    // CodingKeys Swift nomlarini JSON maydon nomlariga moslashtiradi
    enum CodingKeys: String, CodingKey {
        case userName = "user_name"
        case postCount = "post_count"
        case isVerified = "is_verified"
    }
}

// Ichma-ich JSON: { "id": 1, "address": { "city": "Toshkent", "zip": "100000" } }
struct Address: Codable {
    let city: String
    let zip: String
}

struct Person: Codable, Identifiable {
    let id: Int
    // Ichma-ich Codable struct ichma-ich JSON ob'ektini avtomatik ko'chiradi
    let address: Address
}

struct DekodlashMisol: View {
    @State private var xabar = "Dekodlash uchun bosing"

    var body: some View {
        VStack(spacing: 20) {
            Text(xabar)
                .multilineTextAlignment(.center)
                .padding()

            Button("JSON dekodla") {
                let json = """
                {"user_name": "Ali", "post_count": 42, "is_verified": true}
                """.data(using: .utf8)!

                do {
                    let profil = try JSONDecoder().decode(UserProfile.self, from: json)
                    xabar = "Foydalanuvchi: \(profil.userName)\nPostlar: \(profil.postCount)\nTasdiqlangan: \(profil.isVerified)"
                } catch {
                    xabar = "Xato: \(error)"
                }
            }
            .buttonStyle(.borderedProminent)
        }
    }
}
QatorVazifasi
struct UserProfile: CodableCodable qo'shish bu strukturaga JSON dekodlash va enkodlash imkoniyatini beradi. Oddiy holatlarda qo'shimcha kod kerak emas.
enum CodingKeys: String, CodingKeySwift nomlari JSON kalit nomlaridan farq qilganda moslashtiruvchi maxsus ichki enum.
case userName = "user_name"Chap tomon β€” Swift xususiyat nomi. O'ng tomon β€” JSON dagi aniq string kalit. Swift dekodlashda bularni moslashtiradi.
struct Address: CodableHar qanday ichma-ich struct ham Codable bo'lishi kerak. Dekoder JSON da address kalitini uchratganda uni Address sifatida rekursiv dekodlaydi.
JSONDecoder().decode(Person.self, from: data)JSONDecoder yaratadi va xom Data ni Person namunasiga aylantiradi. Person.self β€” turni parametr sifatida uzatish usuli.

snake_case β†’ camelCase avtomatik o'tkazish

let decoder = JSONDecoder()
// user_name β†’ userName, post_count β†’ postCount avtomatik o'tkazadi
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decoded = try decoder.decode(UserProfile.self, from: data)

Butun API snake_case kalitlar ishlatsa, bu bitta sozlama barchasini hal qiladi. CodingKeys umuman shart emas β€” strategiyani bir marta belgilang, Swift barcha kalitni avtomatik o'tkazadi.

Ixtiyoriy xususiyatlar

struct Maqola: Codable, Identifiable {
    let id: Int
    let title: String
    // subtitle har doim JSON da bo'lmasligi mumkin
    let subtitle: String?
    let imageURL: URL?
}

JSON maydoni ba'zan yo'q bo'lsa, xususiyatni ixtiyoriy qiling. Kalit yo'qligida Codable xato tashlash o'rniga nil qiymat beradi. Bu haqiqiy API larda juda keng tarqalgan β€” ba'zi javoblar izchil bo'lmaydi.

Ichma-ich tuzilmalar

// JSON: { "name": "Ali", "company": { "name": "SwiftUI.uz" } }
struct Kompaniya: Codable {
    let name: String
}

struct Foydalanuvchi: Codable {
    let name: String
    let company: Kompaniya
}

// Dekodlash chuqurlik qanchalik bo'lishidan qat'iy nazar bir xil
let decoded = try JSONDecoder().decode(Foydalanuvchi.self, from: data)
print(decoded.company.name) // "SwiftUI.uz"

Tezkor ma'lumotnoma

PatternVazifasi
struct Model: CodableAvtomatik encode/decode β€” nomlar mos bo'lganda eng oddiy holat
enum CodingKeys: String, CodingKeyNomlar mos kelmasa JSON β†’ Swift xaritalash
decoder.keyDecodingStrategy = .convertFromSnakeCaseButun API snake_case ishlatsa β€” bir marta belgilang
let xususiyat: Tur?Ba'zan yo'q bo'ladigan JSON maydonlari uchun ixtiyoriy
struct IchmaIch: CodableHar qanday ichma-ich struct ham Codable bo'lishi kerak

🎯 Topshiriq: haqiqiy API dekodlash

https://jsonplaceholder.typicode.com/users dan foydalanuvchilar oling. Javobni ko'ring β€” address ichma-ich ob'ekt: { "street": "...", "city": "..." }. Address struct yarating va User strukturasiga qo'shing. Har bir foydalanuvchi ismi va shahri ko'rsatilgan List yarating.

Buy mea coffee