- Published on
SwiftUI crypto app — qayta ishlatiladigan tarmoq qatlamini yaratish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
SwiftUI crypto app — qayta ishlatiladigan tarmoq qatlamini yaratish
Ushbu darsda biz oldingi darsda yozgan tarmoq kodimizni optimallashtiramiz. Loyihamizda kelajakda boshqa API so'rovlarini ham oson amalga oshirish uchun qayta ishlatiladigan (reusable) tarmoq menejeri — NetworkingManagerni yaratamiz.
Shuningdek, tarmoq xatoliklarini konsolda chiroyli emoji belgilar bilan ko'rsatadigan maxsus NetworkingError xatoliklar klassini tuzamiz.
1. NetworkingManager utility klassini yaratish
Loyihada utilities nomli yangi guruh (Folder) yaratamiz va uning ichida NetworkingManager.swift faylini ochamiz.
Ushbu klass statik funksiyalardan iborat bo'lib, ob'ekt yaratmasdan to'g'ridan-to'g'ri chaqirish imkonini beradi:
import Foundation
import Combine
class NetworkingManager {
// Maxsus xatoliklar enumi (LocalizedError protokoli bilan)
enum NetworkingError: LocalizedError {
case badURLResponse(url: URL) // Noto'g'ri server javobi uchun (URL manzili bilan)
case unknown // Noma'lum xatolik uchun
// Konsolda ko'rinadigan xato tavsifini o'zgartiramiz
var errorDescription: String? {
switch self {
case .badURLResponse(url: let url):
return "🔥 Serverdan noto'g'ri javob keldi. URL: \(url.absoluteString)"
case .unknown:
return "⚠️ Noma'lum xatolik yuz berdi"
}
}
}
// Tarmoqdan ma'lumot yuklash uchun umumiy (generic) funksiya
static func download(url: URL) -> AnyPublisher<Data, Error> {
return URLSession.shared.dataTaskPublisher(for: url)
// Fondagi oqimda ishga tushirish
.subscribe(on: DispatchQueue.global(qos: .default))
// Server javobini tekshirish uchun yordamchi funksiyani chaqiramiz
.tryMap({ try handleURLResponse(output: $0, url: url) })
// Natijani asosiy oqimga (Main Thread) qaytarish
.receive(on: DispatchQueue.main)
// Combine zanjiri turlarini yashirish va sodda AnyPublisher qaytarish
.eraseToAnyPublisher()
}
// Server javobini va HTTP status kodini tekshiruvchi funksiya
static func handleURLResponse(output: URLSession.DataTaskPublisher.Output, url: URL) throws -> Data {
guard let response = output.response as? HTTPURLResponse,
response.statusCode >= 200 && response.statusCode < 300 else {
throw NetworkingError.badURLResponse(url: url)
}
return output.data
}
// Obunaning yakunlanishini (Completion) boshqaruvchi umumiy funksiya
static func handleCompletion(completion: Subscribers.Completion<Error>) {
switch completion {
case .finished:
break
case .failure(let error):
print(error.localizedDescription)
}
}
}
2. CoinDataService kodini optimallashtirish
Endi CoinDataService fayliga o'tib, yuklash kodlarini yangi yaratgan NetworkingManager yordamida ancha qisqartiramiz:
import Foundation
import Combine
class CoinDataService {
@Published var allCoins: [CoinModel] = []
private var coinSubscription: AnyCancellable?
init() {
getCoins()
}
private func getCoins() {
guard let url = URL(string: "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") else { return }
// NetworkingManager-dan foydalanib yuklashni amalga oshiramiz
coinSubscription = NetworkingManager.download(url: url)
// Decode amali faqat shu modelga tegishli bo'lgani uchun servis ichida qoladi
.decode(type: [CoinModel].self, decoder: JSONDecoder())
.sink(receiveCompletion: NetworkingManager.handleCompletion, receiveValue: { [weak self] (returnedCoins) in
self?.allCoins = returnedCoins
self?.coinSubscription?.cancel()
})
}
}
3. Kodni ajratishning afzalliklari
Nega biz tarmoq so'rovini alohida klassga ajratdik?
- Reusability (Qayta foydalanish): Kelajakda ilovada 5 xil API so'rovi bo'lsa ham, barchasida ayni bir
NetworkingManager.download(url:)funksiyasini yozib ketishimiz mumkin. Kod qayta-qayta yozilmaydi. - Cleaner Code (Toza kod): Servis fayllarimiz juda sodda va faqat o'zining modelini boshqarish bilan band bo'ladi.
- Advanced Error Handling: Xatolik yuz berganda qaysi URL muammo yaratayotganini emojilar yordamida konsolda darhol ajratib olamiz.
Keyingi darsda biz ushbu tarmoq qatlamidan foydalanib, har bir kriptovalyutaning ikonkasini (Coin Image) internetdan yuklab olishni va kesh tizimini yaratishni o'rganamiz! 🚀