From a9473be9373b0f7e625652ece458f9ad67e1ae9d Mon Sep 17 00:00:00 2001 From: songyc macbook Date: Mon, 13 Jul 2026 19:40:46 +0900 Subject: [PATCH] fix(diary): clean up empty entries created by merely viewing a day MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 일기 상세는 진입만 해도 DiaryEntry를 생성(loadEntry)해서, 열람만 한 날짜의 빈 엔트리가 스토어와 CloudKit에 계속 쌓였다. 달력 화면 onAppear에서 완전히 빈 엔트리만 정리한다 (상세에서 달력으로 돌아올 때마다 실행되고, 이 수정 이전에 쌓인 빈 엔트리도 함께 청소됨). 보존 조건을 엄격히 판정: - hasContent(기분·할 일·내용 있는 페이지)는 물론 - 달력 마커에 안 잡히는 캘린더 일정(calendarEventIDs)·타임테이블 필터(hiddenActionIDs) 선택이 있으면 보존 - 아직 내용 없는 노트 페이지를 만들어 둔 날도 보존 (페이지 0개일 때만 삭제) 검증(iPad 시뮬레이터, 스토어 직접 조회): - 열람만 하고 나간 빈 엔트리 → 달력 재진입 시 삭제 (1건 → 0건) - 타임테이블 필터만 설정한 엔트리 → 정리 후에도 보존, 재진입 시 필터 배지(1)와 숨김 상태 유지 확인 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7 --- myApp/HaruDanim/CLAUDE.md | 1 + myApp/HaruDanim/IOS/Views/DiaryView.swift | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/myApp/HaruDanim/CLAUDE.md b/myApp/HaruDanim/CLAUDE.md index a584a4c..100678a 100644 --- a/myApp/HaruDanim/CLAUDE.md +++ b/myApp/HaruDanim/CLAUDE.md @@ -182,6 +182,7 @@ xcrun xcstringstool sync IOS/Localizable.xcstrings --stringsdata "${files[@]}" ### 6.7 일기 탭 (iPad 전용, 프리미엄 — `DiaryView`, `DiaryNotePage`, `DiaryCalendarEvents`, `DiaryExportSheet`) - 루트: 월 달력(작성일에 기분 이모지/연필 마커), 날짜 탭 → 일기 상세. 툴바에서 기간/복수 날짜 내보내기(PDF=페이지별 1장, 이미지=세로 스티치 PNG, 2배율) +- 상세는 진입만 해도 엔트리를 생성(loadEntry)하므로, 달력 onAppear가 **완전히 빈 엔트리만 정리**(기분·할일·페이지 없음 + calendarEventIDs·hiddenActionIDs 비어있음 + 페이지 0개 — 캘린더/필터 선택이나 빈 노트 페이지가 있으면 보존) - 상세: 좌우 페이지 넘김. 1페이지=하루 정리 요약, 이후=펜슬 노트, 마지막=페이지 추가 자리 - **요약 페이지 섹션** (표시·순서는 "첫 화면 구성" 시트, 전 날짜 공통, standard defaults): 오늘 기분(대형 정사각 타일: 이모지/사진) · 요약 지표 · 이 날의 목표(그날 기준 다짐 현황, 주간/월간은 그날까지 누적) · 오늘 할 일 · 타임테이블 · 기록 상세 · 통계 막대. 화면 720pt 이상이면 타임테이블 좌측 고정 2컬럼 - 타임테이블 카드 우상단 버튼: **필터**(그날 기록된 행동만 나열된 팝업에서 표시 선택, 날짜별 저장 `hiddenActionIDs`, 숨긴 개수 노란 배지 — 타임테이블에만 적용, 요약 수치·기록 목록은 전체 유지) + **캘린더**(그날의 EKEvent 선택, 날짜별 저장, 외곽선 스타일 블록). 둘 다 내보내기에 동일 반영 diff --git a/myApp/HaruDanim/IOS/Views/DiaryView.swift b/myApp/HaruDanim/IOS/Views/DiaryView.swift index e5dfc47..168f7a9 100644 --- a/myApp/HaruDanim/IOS/Views/DiaryView.swift +++ b/myApp/HaruDanim/IOS/Views/DiaryView.swift @@ -90,6 +90,9 @@ struct DiaryRootView: View { DiaryExportSheet() } .onAppear { + // 일기 상세는 진입만 해도 엔트리를 만들므로(loadEntry), 달력으로 돌아올 때 + // 아무 흔적도 남기지 않은 빈 엔트리를 정리한다 (CloudKit에 빈 레코드 누적 방지) + cleanupEmptyEntries() #if DEBUG if UserDefaults.standard.bool(forKey: "diaryShowExport") { showingExport = true @@ -98,6 +101,22 @@ struct DiaryRootView: View { } } + /// 완전히 빈 엔트리만 삭제. hasContent(기분·할 일·내용 있는 페이지)뿐 아니라 + /// 달력 마커에는 안 잡혀도 사용자에게 의미 있는 캘린더 일정·타임테이블 필터 선택이 + /// 있으면 보존하고, (아직 내용 없는) 노트 페이지를 만들어 둔 날도 보존한다. + private func cleanupEmptyEntries() { + var changed = false + for entry in diaryEntries + where !entry.hasContent + && entry.calendarEventIDs.isEmpty + && entry.hiddenActionIDs.isEmpty + && (entry.pagesStorage ?? []).isEmpty { + context.delete(entry) + changed = true + } + if changed { try? context.save() } + } + /// 작성된 일기(내용 있는 것만)를 하루 키로 색인 private var entriesByDay: [Date: DiaryEntry] { var result: [Date: DiaryEntry] = [:]