- Published on
SwiftUI crypto app — jonli bozor ma'lumotlarini API dan yuklab ko'rsatish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
SwiftUI crypto app — jonli bozor ma'lumotlarini API dan yuklab ko'rsatish
Oldingi darsda statistika ko'rish uchun view va model tayyorladik, lekin ularda hali haqiqiy ma'lumot yo'q edi. Bu darsda biz CoinGecko API dan global bozor ma'lumotlarini yuklab olamiz — bozor kapitalizatsiyasi, 24 soatlik savdo hajmi, Bitcoin ulushi — va ularni statistika ko'rinishida ekranda chiqaramiz.
1. API javobini ko'rish
CoinGecko saytida GET /global endpointi mavjud. Parametrlar talab etilmaydi, shunchaki bajarasiz. Javob quyidagicha keladi:
{
"data": {
"total_market_cap": { "usd": 2580000000000 },
"total_volume": { "usd": 342000000000 },
"market_cap_percentage": { "btc": 42.5, "eth": 18.3 },
"market_cap_change_percentage_24h_usd": 1.2
}
}
Diqqat: bozor ma'lumotlari "data" kalit so'zi ichida keladi, shuning uchun ikki model kerak bo'ladi.
2. MarketDataModel yaratish
models papkasida MarketDataModel.swift faylini yarataymiz. app.quicktype.io yordamida JSON dan Swift struct hosil qilingan, keyin keraksiz maydonlar olib tashlanadi:
import Foundation
// API dan keladigan tashqi qobiq: { "data": { ... } }
struct GlobalData: Codable {
let data: MarketDataModel?
}
// Haqiqiy bozor ma'lumotlari
struct MarketDataModel: Codable {
let totalMarketCap: [String: Double]
let totalVolume: [String: Double]
let marketCapPercentage: [String: Double]
let marketCapChangePercentage24HUsd: Double
// JSON kalitlarida katta-kichik va underscore bor — CodingKeys kerak
enum CodingKeys: String, CodingKey {
case totalMarketCap = "total_market_cap"
case totalVolume = "total_volume"
case marketCapPercentage = "market_cap_percentage"
case marketCapChangePercentage24HUsd = "market_cap_change_percentage_24h_usd"
}
// USD qiymatida bozor kapitalizatsiyasi
var marketCap: String {
if let item = totalMarketCap.first(where: { $0.key == "usd" }) {
return "$" + item.value.formattedWithAbbreviations()
}
return ""
}
// USD qiymatida 24 soatlik savdo hajmi
var volume: String {
if let item = totalVolume.first(where: { $0.key == "usd" }) {
return "$" + item.value.formattedWithAbbreviations()
}
return ""
}
// Bitcoin bozor ulushi (foiz ko'rinishida)
var btcDominance: String {
if let item = marketCapPercentage.first(where: { $0.key == "btc" }) {
return item.value.asPercentString()
}
return ""
}
}
Nima uchun
CodingKeys? API JSON-datotal_market_capdeb keladi, Swift esatotalMarketCapko'rinishini talab qiladi (camelCase).CodingKeysularni bog'laydi.
3. Sonlarni odam o'qishi uchun formatlash
Double+Extensions.swift ga yangi funksiya qo'shamiz. Bu funksiya katta sonlarni qisqartiradi:
// 1234567 -> "1.23M", 1234567890 -> "1.23Bn", 1234567890000 -> "1.23Tr"
func formattedWithAbbreviations() -> String {
let num = abs(Double(self))
let sign = (self < 0) ? "-" : ""
switch num {
case 1_000_000_000_000...:
let formatted = num / 1_000_000_000_000
let stringFormatted = formatted.asNumberString()
return "\(sign)\(stringFormatted)Tr"
case 1_000_000_000...:
let formatted = num / 1_000_000_000
let stringFormatted = formatted.asNumberString()
return "\(sign)\(stringFormatted)Bn"
case 1_000_000...:
let formatted = num / 1_000_000
let stringFormatted = formatted.asNumberString()
return "\(sign)\(stringFormatted)M"
case 1_000...:
let formatted = num / 1_000
let stringFormatted = formatted.asNumberString()
return "\(sign)\(stringFormatted)K"
case 0...:
return "\(sign)\(self.asNumberString())"
default:
return "\(sign)\(self.asNumberString())"
}
}
4. MarketDataService — API ga so'rov yuborish
CoinDataService-ni asosiy shabloniga tayanib, MarketDataService.swift faylini yaratamiz:
import Foundation
import Combine
class MarketDataService {
@Published var marketData: MarketDataModel? = nil
var marketDataSubscription: AnyCancellable?
init() {
getData()
}
func getData() {
guard let url = URL(string: "https://api.coingecko.com/api/v3/global") else { return }
marketDataSubscription = NetworkingManager.download(url: url)
.decode(type: GlobalData.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: NetworkingManager.handleCompletion,
receiveValue: { [weak self] returnedGlobalData in
self?.marketData = returnedGlobalData.data
self?.marketDataSubscription?.cancel()
}
)
}
}
Javob
GlobalDatasifatida dekodlanadi, keyin.datamaydonidanMarketDataModelolinadi.
5. HomeViewModel-ga qo'shish
HomeViewModel.swift-da yangi servisni yaratamiz va unga subscriber qo'shamiz:
// Eski coinDataService nomini refactor qilish:
private let coinDataService = CoinDataService()
// Yangi market data service:
private let marketDataService = MarketDataService()
addSubscribers() ichida yangi subscriber:
// Bozor ma'lumotlarini subscriberga qo'shish
marketDataService.$marketData
.map(mapGlobalMarketData) // MarketDataModel -> [StatisticModel]
.sink { [weak self] returnedStats in
self?.statistics = returnedStats
}
.store(in: &cancellables)
6. mapGlobalMarketData funksiyasi
HomeViewModel-da statistika ma'lumotlarini hosil qiluvchi private funksiya:
private func mapGlobalMarketData(data: MarketDataModel?) -> [StatisticModel] {
var stats: [StatisticModel] = []
guard let data = data else { return stats }
let marketCap = StatisticModel(
title: "Bozor kapitalizatsiyasi",
value: data.marketCap,
percentageChange: data.marketCapChangePercentage24HUsd
)
let volume = StatisticModel(
title: "24 soatlik hajm",
value: data.volume
)
let btcDominance = StatisticModel(
title: "BTC ulushi",
value: data.btcDominance
)
let portfolio = StatisticModel(
title: "Portfel qiymati",
value: "$0.00", // Keyingi darslarda to'ldiriladi
percentageChange: 0
)
stats.append(contentsOf: [marketCap, volume, btcDominance, portfolio])
return stats
}
7. Natija
Simulatorda ilovani ishga tushirsangiz, endi statistika bo'limida haqiqiy API ma'lumotlari ko'rinadi:
- Bozor kapitalizatsiyasi:
$2.58Tr - 24 soatlik hajm:
$342Bn - BTC ulushi:
42.5% - Portfel:
$0.00(hozircha)
"Ko'rdingizmi, yangi API qo'shish qanchalik tez bo'ldi? Tarmoq menejeri va subscriber tizimini oldindan qurib qo'yganimiz sababli, bu bir necha daqiqada amalga oshdi. Mana arxitekturaning kuchi!"
Keyingi darsda biz portfelni boshqarish uchun yangi view yaratamiz. 🚀