데이터 수집(Upbit REST) → 24시간만 추려서 정렬 → 시세 요약 헤더 갱신(Upbit REST) → 차트 렌더링(SwiftUI Chart) → 1분마다 맨 끝 봉만 추가 → 백그라운드/재진입 최적화
Upbit에서 REST 방식으로 가져오는 데이터
헤더(현재가/등락률/거래대금): Upbit REST 티커 API(/ticker
계열)로 조회
분봉(캔들): Upbit REST 분봉 API(/candles/minutes/1
)로 수집
ChartViewModel.init
→ startUpdating()
시작
prices.isEmpty
면 스피너 ON(최초/빈 상태), 아니면 OFF(조용한 갱신)
shouldShowSpinner
: 데이터가 비어있는지 확인해서 비어있으면 최초 실행으로 판단
→ 스피너를 표시하고 전체 로드하는 플래그
↔ 재진입/빠른 화면 전환/일시적인 네트워크 끊김 후 복귀 시 스피너 표시 안하고 전체 로드최초 1회 전체 로드: loadPrices()
UpbitPriceService.fetchPrices()
→ 내부에서 REST /candles/minutes/1
반복 호출(최대 200개 제한 때문에)UpBitAPIService.fetchTicker(by:)
prices
바인딩이후 매 60초 일부 갱신: refreshLatestCandles()
두 Task를 시작하고 await로 기다렸다가 같은 타이밍에 화면에 반영
async let pricesTask = priceService.fetchPrices(...)
async let tickerTask = tickerAPI.fetchTicker(by: ...)
let (prices, tickers) = try await (pricesTask, tickerTask) // 동시에 시작해 기다렸다가 함께 반영
Swift Charts로 렌더링: CandleChartView
RuleMark
, 몸통 = RectangleMark
chartOverlay
앱 상태
.active
→ retry()
(60초 주기 루프 재가동).background
→ stopUpdating()
(루프 중지)
(scenePhase
환경값으로 감지)