Skip to content

탭 둘로 되돌리기 · 리마인더 버그 · 화면 로깅 · 기기 식별 - #31

Merged
dongglehada merged 5 commits into
mainfrom
feat/two-tabs-reminders-device-id
Oct 6, 2026
Merged

dongglehada merged 5 commits into
mainfrom
feat/two-tabs-reminders-device-id

Conversation

@dongglehada

Copy link
Copy Markdown
Contributor

네 가지를 한 브랜치에 커밋 다섯으로 나눠 담았다. 성격이 서로 달라서 하나씩
되돌릴 수 있게 쪼갰다.

1. 탭을 둘로 되돌렸다 (ab38abd)

달력이 첫 탭, 오늘이 둘째. 1.4.0에서 합칠 때의 진단은 되돌리지 않았다 — 앱이
늘 달력으로 열리는데 달력에 입력창이 없었다는 것, 그래서 9월에 셋 중 하나가 할 일을
한 번도 안 만들었다는 것. 첫 탭은 여전히 달력이고 홈 입력창도 그 자리에 있다.
되살린 것은 오늘 할 일로 가는 문 하나다.

지웠던 TodayTodoScreen(662줄)은 되살리지 않았다. 그 화면이 하던 일은 이미
DayTodosContentView가 전부 한다 — 오늘을 보고 있으면 디데이·지난 할 일·날짜 안
정한 할 일 섹션이 붙는다. 같은 것을 두 벌 들면 한쪽만 고쳐지는 날이 오고, 그게
1.3.x에서 오늘 탭과 하루 페이지가 어긋나 있던 이유였다.

  • 탭이라 뒤로 가기가 없다. '↶ 오늘'이 그 길을 맡는다
  • 자정을 넘기면 앱이 앞으로 나올 때 보던 날을 새 오늘로 갈아끼운다 — 탭은 계속
    살아 있어서 그냥 두면 어제가 오늘인 척 남는다
  • 위젯·라이브 액티비티는 하루 페이지를 밀어 넣는 대신 오늘 탭에 선다
  • "오늘 할 일은 여기로 옮겼어요" 안내는 틀린 말이 됐으므로 걷어냈다

2. 리마인더 — 실제 버그 셋 (14a937f)

예약 로직에 테스트가 한 건도 없었다. 계산이 App/에 있어서 테스트 타깃이 닿지
못했다. ReminderPlan(Shared)으로 꺼내고 테스트 20건을 붙였다. 반복 전개와 완료
판정은 TodoSnapshot의 것을 그대로 쓴다 — 한 벌 더 쓰면 달력과 알림이 서로 다른
날짜를 반복일로 보는 날이 온다.

  • 허용한 직후에 재예약이 안 걸렸다. 재예약 키에 권한 상태가 없어서, 실행 직후
    "권한 없음"으로 돌아나간 뒤 사용자가 허용해도 키가 그대로였다. 앱을 뒤로 보냈다
    돌아오기 전까지 알림이 하나도 안 걸려 있었다. 거부한 쪽은 전체 스위치가 함께
    내려가 키가 바뀌었기 때문에, 허용한 쪽만 조용히 비어 있었다
  • 끝낸 할 일의 알림이 안 걷혔다. 키에 완료 여부가 없었다 — 10시 일정을 9시 30분에
    끝내도 9시 50분에 알림이 울렸다. 라이브 액티비티 키에는 처음부터 있었고 알림
    키만 빠져 있었다
  • 리드타임 '시작 시간에'(0분)를 고르면 **"0분 뒤 오후 7시에 시작해요"**가 떴다

예약 방식도 바꿨다. "전부 지우고 다시 깔기"는 지운 직후부터 다시 깔기까지 알림이
하나도 없는 창을 만든다 — .task(id:)는 키가 바뀌는 즉시 취소되므로 할 일을
연달아 고치면 실제로 그 창에서 끊긴다. 이제 없어진 것만 걷어내고 필요한 것은
그대로 다시 깐다(같은 식별자 add는 교체다). 중간에 끊겨도 남은 쪽이 멀쩡하고,
두 번 겹쳐 돌아도 결과가 같다.

3. 화면 로깅 (9f67971)

이미 1.4.2(#29)에 들어가 있었다. 사용처를 전수로 확인했다 — 시트와 밀려 들어오는
페이지 어디에도 빠진 곳이 없다. 남은 구멍은 "지금 어느 화면으로 세어졌나"를 확인할
길이었다(GA4는 하루쯤 지나서야 보이고 DebugView는 따로 켜야 한다).

화면 이동을 콘솔에도 남긴다 — com.Mosco.App / screens에 화면 → today처럼
찍히고 릴리스 빌드에서도 남는다. 남는 것은 화면 이름 하나뿐이다.

4. 기기 식별 (9343f82)

내부 사용자 표시가 계정 하나에 하나였다. iCloud에 "이 사람은 내부"라고만 적혀서,
한 대를 표시하면 같은 Apple 계정의 모든 기기가 같이 빠졌다. 보고서에서 어느 행이
어느 기기인지도 기종 이름으로 눈대중해야 했고, 기종이 같으면 가를 수 없었다.

이제 iCloud에 기기 목록이 들어간다. 각 줄에 짧은 id(8자)와 기종, 내부 표시.

  • mosco://internal은 그 기기만 표시한다. 알림창에 기기 id도 같이 보여준다
  • 기기를 영구히 식별하는 값은 앱이 가질 수 없으므로(identifierForVendor도 앱을
    지우면 바뀐다), 기종이 같고 내부로 표시된 줄이 있으면 그 표시를 물려받는다.
    재설치한 14 Pro는 표시를 다시 얻고, 같은 계정의 다른 기종은 영향이 없다
  • 1.4.2까지의 계정 단위 표시는 등록부로 옮겨 담은 뒤 내린다. 남겨두면 그 뒤에
    추가되는 기기까지 전부 내부가 된다(테스트로 묶었다 — 처음 구현에서 실제로 이게
    깨져서 테스트가 잡아냈다)
  • 사용자 속성 device_id·device_model. 설정 맨 아래에 이 기기의 id(내부로 표시한
    기기에만 보인다, 누르면 복사)

확인

  • App 테스트 233건 통과 (이번에 33건 추가: 알림 20, 기기 13)
  • iOS 시뮬레이터 빌드 / MoscoWidget 빌드 / Mac Catalyst 빌드 통과
  • tools/artifact_check.sh 통과

눈으로 봐야 하는 것

코드와 테스트로는 여기까지다. docs/BACKLOG.md에 [~]로 적어뒀다.

  1. 탭 바가 아이콘만으로 제대로 뜨는지, 오늘 탭이 뒤로 가기 없이 쓸 만한지
  2. 앱을 새로 깔고 알림을 허용한 그 실행에서 알림이 오는지(뒤로 보내지 않고)
  3. 10분 뒤 일정을 만들고 바로 완료했을 때 알림이 오지 않는지
  4. 한 대에서 mosco://internal을 열었을 때 다른 기기가 같이 빠지지 않는지(GA4)

함께 봐주셔야 할 것

  • PRIVACY.md는 공개 문서인데, 새로 싣는 기기 id를 적어야 해서 수집 항목 표에
    두 줄을 더했다. 올리기 전에 한 번 읽어주세요
  • 출시 전에 GA4에 맞춤 측정기준 device_id·device_model을 사용자 범위로
    등록해야 한다. 등록은 지난 데이터에 소급되지 않는다
  • Mosco/App/InfoPlist.xcstrings에 작업 시작 전부터 있던 수정(Xcode가
    CFBundleName·CFBundleDisplayName을 추출하고 서식을 바꾼 것)이 1번 커밋에
    같이 담겼다. 제 작업이 아니라 원래 있던 변경이고 동작에 영향은 없지만, 빼고
    싶으시면 말씀해주세요
  • 알림 Time Sensitive는 결정대로 넣지 않았다. 집중 모드가 리마인더를 삼키는 건
    그대로 남아 있다 — BACKLOG에 적어뒀다

🤖 Generated with Claude Code

dongglehada and others added 5 commits October 6, 2026 19:52
1.4.0에서 하나로 합친 탭을 둘로 되돌린다. 합칠 때의 진단(앱이 늘 달력으로
열리는데 달력에 입력창이 없었다)은 그대로 유효하므로 그때 고친 것은 되돌리지
않는다 — 첫 탭은 여전히 달력이고 홈 입력창도 그 자리에 있다. 되살린 것은
오늘 할 일로 가는 문 하나다.

지웠던 TodayTodoScreen(662줄)은 되살리지 않았다. 그 화면이 하던 일은 이미
DayTodosContentView가 전부 한다 — 오늘을 보고 있으면 디데이·지난 할 일·날짜
안 정한 할 일 섹션이 붙는다. 같은 것을 두 벌 들면 한쪽만 고쳐지는 날이 온다.

- AppTab(Shared) — 첫 탭·위젯 길·로그 이름을 순수 로직으로 두고 테스트로 묶음
- TodayScreen — 하루 페이지를 탭 뿌리로 세운다. 자정을 넘기면 앞으로 나올 때
  보던 날을 새 오늘로 갈아끼운다(탭은 계속 살아 있어서 그냥 두면 어제가 남는다)
- DayTodosContentView.Origin — 탭인지 밀려 들어온 페이지인지로 로그 이름과
  입력창 출처(today_tab / today_page / calendar_day)를 가른다
- 탭 전환은 RootTabView 한 곳에서 센다. 화면에 붙인 logScreen으로는 탭을 셀 수
  없다 — 탭은 한 번 세워지면 살아 있어서 task가 실행당 한 번만 돈다
- 위젯·라이브 액티비티는 하루 페이지를 밀어 넣는 대신 오늘 탭에 선다
- CalendarHomeNotice 삭제 — "오늘 할 일은 여기로 옮겼어요"가 틀린 말이 됐다

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
알림 예약 로직에 테스트가 한 건도 없었다. 계산이 App/의 스케줄러 안에 있어서
테스트 타깃이 닿지 못했다 — ReminderPlan(Shared)으로 꺼내고 테스트 20건을 붙였다.
반복 전개와 완료 판정은 TodoSnapshot의 것을 그대로 재사용한다. 한 벌 더 쓰면
달력과 알림이 서로 다른 날짜를 반복일로 보는 날이 온다.

고친 것:

- **허용한 직후에 재예약이 안 걸렸다.** rescheduleKey에 권한 상태가 없어서,
  실행 직후 "권한 없음"으로 돌아나간 뒤 사용자가 허용해도 키가 그대로였다.
  앱을 뒤로 보냈다 돌아오기 전까지 알림이 하나도 안 걸려 있었다. 거부한 쪽은
  전체 스위치가 함께 내려가 키가 바뀌었기 때문에, 허용한 쪽만 조용히 비었다.
- **끝낸 할 일의 알림이 안 걷혔다.** 키에 완료 여부가 없어서 10시 일정을 9시
  30분에 끝내도 9시 50분에 알림이 울렸다. 라이브 액티비티 키에는 처음부터
  있었고 알림 키만 빠져 있었다.
- **'시작 시간에'(0분)를 고르면 "0분 뒤 오후 7시에 시작해요"가 떴다.**

예약 방식도 바꿨다. "전부 지우고 다시 깔기"는 지운 직후부터 다시 깔기까지
알림이 하나도 없는 창을 만든다 — .task(id:)는 키가 바뀌는 즉시 취소되므로
할 일을 연달아 고치면 실제로 그 창에서 끊긴다. 이제 없어진 것만 걷어내고
필요한 것은 그대로 다시 깐다(같은 식별자 add는 교체다). 중간에 끊겨도
남은 쪽이 멀쩡하고, 두 번 겹쳐 돌아도 결과가 같다.

창 밖에서 시작하는 반복 일정이 64개 한도의 자리를 차지하던 것도 같이 막았다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
화면 로깅은 1.4.2(#29)에 이미 들어갔고 주요 화면 열두 곳이 전부 붙어 있다.
사용처를 전수로 확인했다 — 시트·밀려 들어오는 페이지 어디에도 빠진 곳은 없다.
남은 구멍은 "지금 어느 화면으로 세어졌나"를 확인할 길이었다. GA4는 하루쯤
지나서야 보이고 DebugView는 따로 켜야 한다.

- 화면 이동을 콘솔에도 남긴다(`com.Mosco.App` / `screens`, 릴리스 포함).
  남는 것은 화면 이름 하나뿐이다
- 탭이 둘로 나뉘면서 생긴 이름(`today`)과 입력창 출처(`today_tab`)를
  docs/ANALYTICS.md에 반영. 되살린 탭을 무엇으로 채점할지도 적었다

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
내부 사용자 표시가 계정 하나에 하나뿐이었다. iCloud에 "이 사람은 내부"라고만
적혀서, 한 대를 표시하면 같은 Apple 계정의 모든 기기가 같이 분석에서 빠졌다.
보고서에서 어느 행이 어느 기기인지도 기종 이름으로 눈대중해야 했고, 기종이
같으면 애초에 가를 수 없었다.

이제 iCloud에 기기 **목록**이 들어간다(DeviceIdentity). 각 줄에 짧은 id(8자)와
기종, 내부 표시가 있어서 한 대만 표시할 수 있고 다른 기기에서도 그 목록이 보인다.

- `mosco://internal`은 그 기기만 표시한다. 알림창에 기기 id도 함께 보여준다
- 기기를 영구히 식별하는 값은 앱이 가질 수 없으므로(identifierForVendor도 앱을
  지우면 바뀐다), **기종이 같고 내부로 표시된 줄이 있으면 그 표시를 물려받는다.**
  재설치한 14 Pro는 표시를 다시 얻고 같은 계정의 다른 기종은 영향이 없다
- 1.4.2까지의 계정 단위 표시는 등록부로 옮겨 담은 뒤 **내린다.** 남겨두면 그
  뒤에 추가되는 기기까지 전부 내부로 물려받는다 — 테스트로 묶어뒀다
- 사용자 속성 device_id·device_model을 싣는다. GA4의 기종 열은 때로 그냥
  "iPhone"이라 두 대를 가를 수 없다
- 설정 맨 아래에 이 기기의 id(내부로 표시한 기기에만 보인다, 누르면 복사).
  보고서의 한 줄과 손에 든 기기를 맞추려면 그 값을 기기에서 읽을 수 있어야 한다
- 테스트 13건. PRIVACY.md에 수집 항목으로 적었다(매니페스트는 이미 DeviceID를
  분석 목적·비연결·비추적으로 신고해 둬서 고칠 것이 없었다)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
눈으로 봐야 [x]가 되는 것 다섯 개를 [~]로 남겼다. 무엇을 봐야 하는지도 한 줄씩
적었다 — 다음에 열었을 때 "이거 됐나?"를 다시 추측하지 않게.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dongglehada
dongglehada merged commit e7f295b into main Oct 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant