본문 바로가기

Project/30MinRead

📅 독서 시간을 완료한 날짜 저장하여 표시하기

 

✅ 독서 기간: 3월 23일 ~ 3월 26일 경우 "⚪️ ⚪️ ⚪️ ⚪️" 총 4개로 저장 

✅ "🟢" 당일 독서 시간을 완료할 경우 

✅ "🔴" 당일 독서 시간을 완료 못할 경우 

 

✅ 1. ReadItemModel 검토

extension ReadItemModel {
    var completedDates: [String: Bool] {
        let key = "completed_dates_\(self.id.uuidString)"
        return UserDefaults.standard.dictionary(forKey: key) as? [String: Bool] ?? [:]
    }
}

 

👍 좋은 점

  • UserDefaults 키를 UUID로 고유하게 설정해서 중복 방지 잘 했고
  • 모델 내에서 저장된 날짜별 상태를 간편하게 조회할 수 있어 매우 유용함

 

✅ 2. ReadItemViewModel 검토

func markReadingCompleted(for item: ReadItemModel) {
    let key = "completed_dates_\(item.id.uuidString)"
    var completed = UserDefaults.standard.dictionary(forKey: key) as? [String: Bool] ?? [:]
    let today = Date()

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    let todayKey = formatter.string(from: today)

    completed[todayKey] = true
    UserDefaults.standard.set(completed, forKey: key)

    print("✅ \(item.title)의 \(todayKey) 독서 완료 저장됨")
}



func loadCompletedDates(for item: ReadItemModel) -> [String: Bool] {
    let key = "completed_dates_\(item.id.uuidString)"
    return UserDefaults.standard.dictionary(forKey: key) as? [String: Bool] ?? [:]
}

👍 좋은 점

  • ViewModel에서 모델 외부 저장소를 관리하는 구조가 명확해서 책임 분리가 잘 돼 있음
  • mark와 load가 짝을 이루고 있어서 이후 Cell에서도 재사용 가능

 

✅ 3. TimerViewController.refreshValue() 검토

viewModel.markReadingCompleted(for: readItem)

 

👍 완벽한 타이밍

  • 타이머가 정확히 종료된 시점에서 완료 기록을 저장하는 위치가 맞음
  • 타이머가 중단됐을 경우에는 기록되지 않도록 조건이 자연스럽게 보장됨