데이터 수집(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, 몸통 = RectangleMarkchartOverlay앱 상태
.active → retry()(60초 주기 루프 재가동).background → stopUpdating()(루프 중지)
(scenePhase 환경값으로 감지)