Skip to content

[NM-428] dwell_ms 를 화면 노출 시간 누적으로 변경, dwell_bucket 추가 - #159

Merged
ParkMazorika merged 1 commit into
developfrom
feature/NM-428-dwell-onscreen-time
Sep 1, 2026
Merged

ParkMazorika merged 1 commit into
developfrom
feature/NM-428-dwell-onscreen-time

Conversation

@ParkMazorika

@ParkMazorika ParkMazorika commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

  • NM-428

⚠️ base 가 develop 이 아니라 feature/NM-427-analysis-duration 이다. 두 브랜치가 AnalyticsEvent.swift 의 인접 영역을 건드려 스택으로 쌓았다. #158 이 머지되면 base 가 develop 으로 자동 전환된다. #158 을 먼저 머지할 것.

변경 요약

pill_confirm.dwell_ms 를 "마지막 진입 시각부터의 벽시계"에서 "수정 화면이 실제로 떠 있던 시간의 누적" 으로 바꾸고, 분포용 dwell_bucket 을 추가한다.

변경 내용

무엇이 틀렸었나

사용자가 알약 하나를 확정하는 데 실제로 들인 시간을 재려던 지표인데, 기존 값에는

  • 앱을 백그라운드로 내린 시간이 포함됐고
  • 다른 탭에 가 있던 시간도 포함됐고
  • 뒤로 나갔다 다시 들어오면 새 화면이라 0부터 다시 셌다

어느 쪽도 "고민한 시간"이 아니다. 잠깐 다른 앱 보고 온 사용자가 오래 고민한 사용자로 잡혔다.

어떻게 고쳤나

포함 제외
수정 화면이 보이는 동안 앱 백그라운드
같은 알약의 모든 방문 합 다른 탭에 가 있는 동안
후보 세부정보·이미지 비교 뷰어
  • PillDwellTracker 신규. iOS 는 앱을 백그라운드로 내려도 viewDidDisappear 를 부르지 않는다. 그래서 viewDidAppear/viewDidDisappear 와 didEnterBackground/willEnterForeground 두 쌍을 모두 관측해야 한다. 한 쌍만 보면 백그라운드 시간이 그대로 새어 들어온다.
  • 누적기를 DrugIdentificationCoordinator 가 소유해 PillEditVC 가 다시 만들어져도 값이 이어진다. Coordinator 는 탭당 하나로 앱 수명 내내 살아 있으므로 새 인식 세션마다 reset() 한다.
  • 수동 추가 알약은 애초에 isManual 로 pill_confirm 자체가 나가지 않아 대상이 아니다(NM-187).

dwell_bucket

Int 는 GA4 측정항목으로만 등록되어 분류 축에서 (not set) 이 된다. 같은 이벤트의 edit_count_bucket·edited_attrs 와 교차하면 "많이 고친 알약이 오래 걸리는가"를 바로 볼 수 있다.

unknown
00:00-00:10  00:10-00:30  00:30-01:00
01:00-01:30  01:30-02:00  02:00-02:30  02:30-03:00
03:00-03:30  03:30-04:00  04:00-04:30  04:30-05:00
05:00-10:00  10:00+

1분까지는 기존 구간을 그대로 두고, 그 뒤로 5분까지 30초 단위. mm:ss 고정자리인 이유는 GA4가 문자열을 사전순 정렬해서, 단위를 섞으면 정렬이 시간순과 어긋나기 때문이다.

함께 들어간 것

Projects/App/Project.swift 에 분석 QA용 실행 인자(-FIRDebugEnabled, -FIRAnalyticsDebugEnabled)를 꺼진 채로 스킴에 주입한다. 손으로 넣으면 tuist generate 때마다 날아가서 매번 다시 쳐야 했다. 기본을 꺼 두는 건 켜 두면 모든 개발 실행이 DebugView 로 흘러 QA 세션과 섞이기 때문.

⚠️ 리뷰어가 봐야 할 것

옛 dwell_ms 와 새 dwell_ms 는 의미가 다르다. 같은 축에 놓고 비교하면 안 된다. 리포트에서 이 지표의 추이를 보면 배포 시점에 값이 뚝 떨어지는데, 개선이 아니라 정의가 바뀐 것이다. GA4 주석(annotation)을 달아 두는 게 좋겠다.

테스트

  • 로컬 빌드/실행 확인 (tuist build App Build Succeeded)
  • 정상·에러 케이스 확인

실측 (2026-09-02, 시뮬레이터) — 세 왜곡이 모두 잡혔다.

실험 자리 비움 전체 벽시계 기록된 dwell_ms
변경 전 · 백그라운드 53.8초 102.8초 102.8초 (전부 포함)
변경 후 · 탭 전환 3분 49초 274.9초 45.6초
변경 후 · 백그라운드 4분 0초 317.3초(3차 방문) 236.8초 (1·2차 누적 포함)
  • 탭 전환 실험은 경계 세 개가 모두 screen_view 로 로그에 남아 구간 합 45.569초 vs 기록 45.571초, 0.002초 일치.
  • 재진입 누적 — 같은 알약을 세 번에 나눠 봤고 45.6 + 112.9 + 77.4 초가 그대로 쌓였다. 변경 전이라면 매 방문마다 0으로 리셋됐을 값이다.

앱이 포그라운드로 돌아오는 순간은 어떤 이벤트로도 로그에 남지 않아(viewDidAppear 미호출, Firebase 무발화) 복귀 시각은 조작 시각으로 브래킷했다.

체크리스트

  • PR 제목이 [NM-XXX] 요약 형식
  • 브랜치명 <type>/NM-XXX-요약 형식
  • 커밋 메시지 [NM-XXX] type: 요약 형식
  • 셀프 리뷰 완료

pill_confirm.dwell_ms 의 정의를 "수정 화면에 마지막으로 진입한 시각부터의 벽시계"에서
"수정 화면이 실제로 떠 있던 시간의 누적"으로 바꾼다.

기존 값은 앱을 백그라운드로 내린 시간, 다른 탭에 가 있던 시간이 모두 섞여 있었고,
뒤로 나갔다 다시 들어오면 새 화면이라 0부터 다시 셌다. 사용자가 알약 하나를 확정하는 데
실제로 들인 시간을 재려던 지표인데 그 어느 쪽도 맞지 않았다.

- PillDwellTracker 신규. iOS 는 앱을 백그라운드로 내려도 viewDidDisappear 를 부르지
  않으므로 viewDidAppear/viewDidDisappear 와 didEnterBackground/willEnterForeground
  두 쌍을 모두 관측해야 한다.
- 누적기를 Coordinator 가 소유해 PillEditVC 가 다시 만들어져도 값이 이어진다.
  Coordinator 는 탭당 하나로 앱 수명 내내 살아 있어 새 인식 세션마다 reset() 한다.
- 수동 추가 알약은 애초에 isManual 로 pill_confirm 자체가 나가지 않아 대상이 아니다.
- dwell_bucket 추가 — Int 는 GA4 측정항목으로만 등록되어 분류 축에서 (not set) 이 된다.
  1분까지는 기존 구간을 두고 그 뒤로 5분까지 30초 단위. 라벨이 mm:ss 인 이유는 초와 분을
  섞으면(30초-1분 · 1-2분) 사전순 정렬이 시간순과 어긋나기 때문이다.

⚠️ 옛 dwell_ms 와 새 dwell_ms 는 의미가 달라 같은 축에 놓고 비교하면 안 된다.

실측(2026-09-02, 시뮬레이터)
- 탭 전환 3분 49초 자리비움: 전체 벽시계 274.9초 → 기록 45.6초.
  경계 세 개가 모두 screen_view 로 남아 구간 합 45.569초 vs 기록 45.571초.
- 백그라운드 4분: 3차 방문 벽시계 317.3초 → 기록 236.8초(45.6+112.9+77.4 누적).

함께: 분석 QA용 실행 인자(-FIRDebugEnabled 등)를 꺼진 채로 스킴에 주입한다.
손으로 넣으면 tuist generate 때마다 날아가서 매번 다시 쳐야 했다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qc4S5fQbGW3fnZMh7bPb8
Base automatically changed from feature/NM-427-analysis-duration to develop September 1, 2026 21:05
@ParkMazorika ParkMazorika self-assigned this Sep 1, 2026
@ParkMazorika ParkMazorika added the enhancement New feature or request label Sep 1, 2026
@ParkMazorika
ParkMazorika merged commit de1f6d1 into develop Sep 1, 2026
@ParkMazorika
ParkMazorika deleted the feature/NM-428-dwell-onscreen-time branch September 1, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant