feat: Apple Watch 실시간 러닝 연동 및 심박수 존 시각화#276
Open
thingineeer wants to merge 19 commits intoRunnect:developfrom
Open
feat: Apple Watch 실시간 러닝 연동 및 심박수 존 시각화#276thingineeer wants to merge 19 commits intoRunnect:developfrom
thingineeer wants to merge 19 commits intoRunnect:developfrom
Conversation
fix: 코스 발견 배너 이미지 미표시 수정
- watchapp2-container(RNWatch) 레거시 타겟 제거 - RNWatch Watch App을 iOS 앱에 직접 임베드하도록 변경 - 빌드 스킴에 Watch App 타겟 추가
- CountDownVC에서 카운트다운 완료 시 Watch에 러닝 시작 알림 - RunTrackingVC에서 5초 간격 러닝 데이터 Watch 전송 - Watch에서 종료 명령 수신 시 iPhone 러닝 종료 처리 - RunningRecordVC에서 기록 저장 후 Watch 상태 초기화
- iPhone 앱과 동일한 Runnect 아이콘을 Watch 앱에 적용 - 1024x1024 원본 이미지로 자동 리사이즈 설정
- CocoaPods 1.15.0 → 1.16.2 업데이트 - rexml 버전 제약 완화 - HealthKit entitlements 정리
- WatchSessionService에 sendCountdownStarted() 메서드 추가 - CountDownVC에서 카운트다운 시작 시점에 Watch 알림 전송 - WatchSessionManager에서 countdownStarted 메시지 수신 처리 - 카운트다운 메시지 누락 시 runStarted fallback 처리
- CourseProgressBar 컴포넌트 신규 생성 - 시작(S), 현재위치(러너 아이콘), 끝(깃발) 마커 표시 - GeometryReader 기반 실시간 위치 애니메이션 - 현재거리/전체거리 텍스트 표시 - ActiveRunView에서 기존 ProgressView를 CourseProgressBar로 교체
- HeartRateZone enum 모델 생성 (Zone 1~5, 색상, MHR% 기반 계산) - WorkoutManager에 currentZone 프로퍼티 추가 및 자동 존 계산 - Zone 4 이상 진입 시 햅틱 알림 (HapticManager.heartRateZoneAlert) - 최대 심박수 기본값 190 (220-30세)
- ActiveRunView 심박수 텍스트/아이콘 색상을 현재 존 색상으로 동적 변경 - Zone 배지 캡슐 추가 (Z1~Z5, 존 색상 배경) - RunSummaryView 평균 심박수 셀에 존 배지 표시 - heartRate 0일 때 Zone 배지 숨김 처리
- RNAlertVC로 "러닝을 종료하시겠습니까?" 확인 다이얼로그 표시 - 종료 시 Watch 데이터 전송 중지 및 상태 초기화 - 취소 시 러닝 계속 진행
- CLLocationManager를 활용한 실제 뛴 거리 누적 계산 - Watch 데이터 동기화 시 코스 총 거리 대신 실제 GPS 거리 전송 - 러닝 종료/취소 시 위치 추적 정리 - 정확도 20m 이내, 최소 이동 거리 5m 필터링 적용
- 러닝 종료 버튼에 확인 알럿 추가 (뒤로가기와 동일한 UX) - 러닝 기록 화면에서 뒤로가기 시 루트 화면으로 이동하도록 수정
- NativeAdCVC 셀 생성 (CourseListCVC와 동일한 카드 스타일) - CourseDiscoveryVC 코스 리스트에 매 10개마다 네이티브 광고 삽입 - GADAdLoader로 최대 3개 네이티브 광고 사전 로드 - 광고 위치 계산 헬퍼 메서드 추가 (isAdPosition, courseIndex 등) - 기존 shouldShowAds 조건 재활용 (3회 이상 실행 + 등록 사용자) - 광고 로드 실패 시 코스만 표시하는 graceful fallback
- 네이티브 광고 프로덕션 ID를 빈 문자열로 설정하여 릴리즈에서 테스트 광고가 노출되지 않도록 처리 - AdMob 콘솔에서 프로덕션 네이티브 광고 단위 ID 발급 후 교체 필요
- init 시점에 contentView.frame.width가 0일 수 있는 문제 해결 - 고정 높이 대신 snp.width.multipliedBy(124/174) 사용
- 0.7초 인위적 지연 제거하여 즉시 데이터 로딩 - reloadData 대신 performBatchUpdates + insertItems로 자연스러운 셀 삽입 - willDisplay 기반 프리페치 트리거 (threshold: 6)로 미리 다음 페이지 로드 - Kingfisher ImagePrefetcher로 이미지 사전 캐싱 - CourseListCVC 중복 이미지 로딩 방지 및 prepareForReuse 최적화 - 첫 페이지만 로딩 인디케이터 표시 (페이지네이션은 백그라운드 로딩)
- Watch 앱 버전 2.3.1 → 2.4.0 - 한국어 릴리즈 노트 작성 (Watch 출시, 성능 개선, 러닝 UX) - 영어 리뷰 노트 업데이트 - Watch 스크린샷 교체 (심박수 존, 프로그레스바 반영)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
변경 내용
Watch 러닝 연동
심박수 존 시각화
Watch UI
GPS 러닝 거리 추적
러닝 UX 개선
코스 발견 네이티브 광고
프로젝트 구조
📊 코스 발견 페이지네이션 성능 개선 (Before → After)
데이터 로딩 지연시간
셀 렌더링 효율
reloadData(전체 N개 셀 재생성)insertItems(새 10개만 삽입)이미지 로딩 최적화
kf.cancelDownloadTask()로딩 인디케이터 UX
프리페치 트리거 방식
scrollViewDidScroll(매 스크롤 이벤트마다 호출)willDisplay(셀 표시 시점에만 호출)Test plan