데이터를 받아오기 위해 CoinDataService 클라스를 생성합니다.
CoinDataService.swift
import Foundation
import Combine
class CoinDataService {
@Published var allCoins: [CoinModel] = []
var coinSubscription: AnyCancellable?
init() {
getCoin()
}
private func getCoin() {
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 }
coinSubscription = URLSession.shared.dataTaskPublisher(for: url)
.subscribe(on: DispatchQueue.global(qos: .default)) // 백그라운드 스레드에서 실행하라. 기본적으로 백그라운드 스레드에서 작업이 되지만 확실히 명시해준다.
.tryMap { (output) -> Data in
guard let response = output.response as? HTTPURLResponse,
response.statusCode == 200 else {
throw URLError(.badServerResponse)
}
return output.data
}
.receive(on: DispatchQueue.main) //메인 스레드에서 실행하라
.decode(type: [CoinModel].self, decoder: JSONDecoder())
.sink { (completion) in
switch completion {
case .finished:
break
case .failure(let error):
print(error.localizedDescription)
}
} receiveValue: { [weak self] (returnCoins) in
self?.allCoins = returnCoins
self?.coinSubscription?.cancel()
}
}
}
Combine으로 작성하는 것은 지난 SwiftSoup를 연습할 때 이후로 두번째인데요.
조금더 이해도가 상승한 느낌입니다..!
HomeViewModel.swift
import Foundation
import Combine
class HomeViewModel: ObservableObject {
@Published var allCoins: [CoinModel] = []
@Published var portfolioCoins: [CoinModel] = []
private let dataService = CoinDataService()
private var cancellables = Set<AnyCancellable>()
init() {
addSubscribers()
}
func addSubscribers() {
dataService.$allCoins //Subcriber
.sink { [weak self] (returnedCoins) in
self?.allCoins = returnedCoins
}
.store(in: &cancellables)
}
}
CoinDataService에서 업데이트된 내용을 잘 받을 수 있도록 작성해줍니다.
흐름을 살펴보면 다음과 같습니다.
HomeView -> HomeViewModel -> dataService = CoinDataService()에서 데이터 받아오기 -> $allCoins로 CoinDataService의 allCoins[]를 조회(레퍼런스)하기 -> 참조한 데이터를 HomeViewModel의 allCoins[]에 업데이트
데이터 받아오기 완료!
'Project > SwiftUI 블록와이드' 카테고리의 다른 글
[SwiftUI Project] 검색화면으로 전환하기 NavigationLink (0) | 2022.09.14 |
---|---|
[SwiftUI Project] 재사용 가능한 NetworkingManager.. with Combine (0) | 2022.09.14 |
[SwiftUI Project] HomeViewModel과 HomeView 연결, UI 작업 (0) | 2022.09.13 |
[SwiftUI Project] CoinRowView와 Double Formatter (0) | 2022.09.12 |
[SwiftUI Project] PreviewProvider Extension (0) | 2022.09.12 |
댓글