Published on

SwiftUI crypto app — API javobi asosida CoinModel yaratish

Authors

SwiftUI crypto app — API javobi asosida CoinModel yaratish

Ushbu darsda biz CoinGecko API-dan keladigan murakkab JSON ma'lumotlariga mos keluvchi CoinModel modelini yaratamiz. Ushbu model ilovamizning deyarli barcha qismlarida ma'lumot uzatish va ko'rsatish uchun xizmat qiladi.


1. CoinGecko API ma'lumotlari bilan tanishish

Kriptovalyuta ma'lumotlarini olish uchun CoinGecko bepul API xizmatidan foydalanamiz. Tarmoqdan quyidagi URL orqali 250 ta eng mashhur tangalar ma'lumotlarini yuklab olamiz:

https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=250&page=1&sparkline=true&price_change_percentage=24h

Ushbu so'rov bizga har bir tanga uchun quyidagicha JSON formatidagi ma'lumotlarni qaytaradi:

[
  {
    "id": "bitcoin",
    "symbol": "btc",
    "name": "Bitcoin",
    "image": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png",
    "current_price": 54321.0,
    "market_cap": 1018388902094,
    "market_cap_rank": 1,
    ...
  }
]

2. CoinModel modelini yaratish

Loyihamizda yangi models papkasini ochib, uning ichida CoinModel.swift faylini yaratamiz. Modelni JSON-dan oson o'qish (decode qilish) uchun Codable va ro'yxatlarda foydalanish uchun Identifiable protokollariga moslaymiz:

import Foundation

// Identifiable va Codable protokollari
struct CoinModel: Identifiable, Codable {
    let id, symbol, name: String
    let image: String
    let currentPrice: Double
    let marketCap, marketCapRank, fullyDilutedValuation, totalVolume: Double?
    let high24H, low24H: Double?
    let priceChange24H, priceChangePercentage24H: Double?
    let marketCapChange24H, marketCapChangePercentage24H: Double?
    let circulatingSupply, totalSupply, maxSupply, ath: Double?
    let athChangePercentage: Double?
    let athDate: String?
    let atl, atlChangePercentage: Double?
    let atlDate: String?
    let lastUpdated: String?
    let sparklineIn7D: SparklineIn7D?
    let priceChangePercentage24HInCurrency: Double?

    // Foydalanuvchi portfelidagi tangalar sonini saqlash uchun (API-dan kelmaydi)
    let currentHoldings: Double?

    // Identifiable protokoli uchun
    var rank: Int {
        Int(marketCapRank ?? 0)
    }

    // Portfeldagi tangalar qiymatini hisoblash
    var currentHoldingsValue: Double {
        (currentHoldings ?? 0) * currentPrice
    }
}

struct SparklineIn7D: Codable {
    let price: [Double]?
}

3. Custom CodingKeys yaratish

API-dan keladigan JSON ma'lumotlaridagi kalit so'zlar odatda snake_case (masalan, current_price) formatida yoziladi. Swift standartiga ko'ra o'zgaruvchilarni camelCase (currentPrice) formatida yozishimiz uchun CodingKeys nomli maxsus enum yaratamiz:

extension CoinModel {
    enum CodingKeys: String, CodingKey {
        case id, symbol, name, image
        case currentPrice = "current_price"
        case marketCap = "market_cap"
        case marketCapRank = "market_cap_rank"
        case fullyDilutedValuation = "fully_diluted_valuation"
        case totalVolume = "total_volume"
        case high24H = "high_24h"
        case low24H = "low_24h"
        case priceChange24H = "price_change_24h"
        case priceChangePercentage24H = "price_change_percentage_24h"
        case marketCapChange24H = "market_cap_change_24h"
        case marketCapChangePercentage24H = "market_cap_change_percentage_24h"
        case circulatingSupply = "circulating_supply"
        case totalSupply = "total_supply"
        case maxSupply = "max_supply"
        case ath
        case athChangePercentage = "ath_change_percentage"
        case athDate = "ath_date"
        case atl
        case atlChangePercentage = "atl_change_percentage"
        case atlDate = "atl_date"
        case lastUpdated = "last_updated"
        case sparklineIn7D = "sparkline_in_7d"
        case priceChangePercentage24HInCurrency = "price_change_percentage_24h_in_currency"
        case currentHoldings
    }
}

4. Portfel miqdorini yangilash funksiyasi

Foydalanuvchi o'z portfelidagi tangalar sonini o'zgartirganda, biz mavjud CoinModel ma'lumotlarini o'zgartirmasdan, yangilangan currentHoldings bilan yangi model obyektini qaytaradigan yordamchi funksiya yaratamiz (chunki modelimiz struct bo'lib, o'zgarmas immutable hisoblanadi):

extension CoinModel {
    func updateHoldings(amount: Double) -> CoinModel {
        return CoinModel(
            id: id, symbol: symbol, name: name, image: image,
            currentPrice: currentPrice, marketCap: marketCap,
            marketCapRank: marketCapRank, fullyDilutedValuation: fullyDilutedValuation,
            totalVolume: totalVolume, high24H: high24H, low24H: low24H,
            priceChange24H: priceChange24H, priceChangePercentage24H: priceChangePercentage24H,
            marketCapChange24H: marketCapChange24H, marketCapChangePercentage24H: marketCapChangePercentage24H,
            circulatingSupply: circulatingSupply, totalSupply: totalSupply,
            maxSupply: maxSupply, ath: ath, athChangePercentage: athChangePercentage,
            athDate: athDate, atl: atl, atlChangePercentage: atlChangePercentage,
            atlDate: atlDate, lastUpdated: lastUpdated, sparklineIn7D: sparklineIn7D,
            priceChangePercentage24HInCurrency: priceChangePercentage24HInCurrency,
            currentHoldings: amount
        )
    }
}

Ushbu funksiya kelajakda foydalanuvchining shaxsiy portfelini boshqarishda juda asqotadi.

Keyingi darsda biz ushbu model yordamida asosiy ekranda tangalar ro'yxatini va ularning satrlarini (CoinRowView) dizayn qilishni o'rganamiz! 🚀

Buy mea coffee