Skip to content

Conversation

@doyeonk429
Copy link
Member

@doyeonk429 doyeonk429 commented Nov 11, 2025

🔗 관련 이슈

📘 작업 유형

  • ✨ Feature (기능 추가)
  • 🐞 Bugfix (버그 수정)
  • 🔧 Refactor (코드 리팩토링)
  • ⚙️ Chore (환경 설정)
  • 📝 Docs (문서 작성 및 수정)
  • ✅ Test (기능 테스트)
  • 🎨 style (코드 스타일 수정)

📙 작업 내역

  • remoteConfig 플래그 처리
  • remoteConfig repo, fetch RemoteAppVersion usecase 구현
  • 강제 업데이트, 업데이트 안내 alert 분기

🧪 테스트 내역

  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

🎨 스크린샷 또는 시연 영상 (선택)

스크린샷 2025-11-11 오후 10 41 41
Simulator.Screen.Recording.-.ReedDefaultSize.-.2025-11-11.at.22.42.30.mp4

✅ PR 체크리스트

  • 커밋 메시지가 명확합니다
  • PR 제목이 컨벤션에 맞습니다
  • 관련 이슈 번호를 작성했습니다
  • 기능이 정상적으로 작동합니다
  • 불필요한 코드를 제거했습니다

💬 추가 설명 or 리뷰 포인트 (선택)

App Store 이동 테스트 관련

  • App Store 이동 기능은 시뮬레이터에서 정상적으로 연결되지 않습니다. (시뮬레이터 환경적 한계로 보입니다.)
  • 실기기에서 테스트 시, 업데이트 버튼을 누르면 App Store로 정상 이동하는 것을 확인했습니다. 리뷰 시 이 점 참고 부탁드립니다.

업데이트 얼럿(Alert) 구현 관련

  • 최신 버전 사용률을 높이는 것이 서비스에 긍정적이라 판단하여, 기존 강제 업데이트(강업) 로직 외에 신규 버전 출시를 안내하는 '권장' 업데이트 얼럿을 추가로 구현하였습니다.

Summary by CodeRabbit

  • 새로운 기능

    • Firebase Remote Config 연동으로 원격에서 앱 버전 정보를 가져와 업데이트 판정 지원
    • 앱 시작 시 원격 버전 확인 후 자동으로 업데이트 안내 표시
  • 수정

    • 업데이트 흐름 개선: 최소 버전 미만은 강제 업데이트, 최신 버전 미만은 선택 업데이트(“나중에 하기” 가능)
    • 업데이트 판단 관련 로그 및 제어 흐름 개선

@doyeonk429 doyeonk429 self-assigned this Nov 11, 2025
@github-actions github-actions bot requested a review from clxxrlove November 11, 2025 14:11
@coderabbitai
Copy link

coderabbitai bot commented Nov 11, 2025

Walkthrough

Firebase Remote Config를 도입해 원격 앱 버전 정보를 조회하는 리포지토리, 유스케이스, 엔티티 및 DI 바인딩을 추가하고, 앱 시작 시 AppCoordinator에서 강제/선택적 업데이트 로직을 통합합니다. (원격값 fetch 및 버전 비교 기반 분기)

Changes

Cohort / File(s) 요약
프로젝트 의존성
src/Projects/BKData/Project.swift, src/Projects/Booket/Project.swift
FirebaseRemoteConfig 외부 의존성 추가
데이터 계층 - 어셈블리
src/Projects/BKData/Sources/DataAssembly.swift
FirebaseRemoteConfig import 추가 및 RemoteConfigRepository 싱글톤 등록(디버그에서 minimumFetchInterval = 0)
데이터 계층 - 저장소 구현
src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift
DefaultRemoteConfigRepository 추가: RemoteConfig 주입, fetchAndActivate()로 원격값 가져와 RemoteAppVersion 발행, 기본값 설정 로직 포함
도메인 계층 - 인터페이스 & 엔티티
src/Projects/BKDomain/Sources/Interface/Repository/RemoteConfigRepository.swift, src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift, src/Projects/BKDomain/Sources/Entity/RemoteAppVersion.swift
RemoteConfigRepository 프로토콜, FetchRemoteAppVersionUseCase 프로토콜, RemoteAppVersion 엔티티 추가
도메인 계층 - 유스케이스 구현 & 어셈블리
src/Projects/BKDomain/Sources/UseCase/DefaultFetchRemoteAppVersionUseCase.swift, src/Projects/BKDomain/Sources/DomainAssembly.swift
DefaultFetchRemoteAppVersionUseCase 구현 및 DI 등록(Assembly에 바인딩 추가)
프레젠테이션 계층 변경
src/Projects/BKPresentation/Sources/AppCoordinator.swift, src/Projects/Booket/Sources/SceneDelegate.swift
fetchRemoteAppVersionUseCase 의존성 주입 추가, AppCoordinator에서 원격버전 비교 로직 통합(강제/선택적 업데이트 분기) 및 presentUpdateSheet(isForced:) 시그니처/동작 변경

Sequence Diagram(s)

sequenceDiagram
    participant App as 앱 시작
    participant SC as SceneDelegate
    participant AC as AppCoordinator
    participant UC as FetchRemoteAppVersionUseCase
    participant Repo as RemoteConfigRepository
    participant Firebase as FirebaseRemoteConfig
    participant UI as 업데이트 다이얼로그

    App->>SC: startScene()
    SC->>AC: init(fetchRemoteAppVersionUseCase)
    AC->>UC: execute()
    UC->>Repo: fetchRemoteAppVersions()
    Repo->>Firebase: fetchAndActivate()
    Firebase-->>Repo: 활성화 성공 + 설정값
    Repo->>Repo: latestVersion, minimumRequiredVersion 읽음
    Repo-->>UC: RemoteAppVersion 발행
    UC-->>AC: RemoteAppVersion 전달

    rect rgb(240,250,240)
    note right of AC: 버전 비교
    AC->>AC: currentVersion 비교
    alt current < minimum
        AC->>UI: presentUpdateSheet(isForced: true)
        note right of UI: 강제 업데이트(종료/업데이트 유도)
    else current < latest
        AC->>UI: presentUpdateSheet(isForced: false)
        note right of UI: 선택적 업데이트(나중에 하기 허용)
    else
        AC->>App: 정상 흐름 진행
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

검토 시 주의 필요 영역:

  • src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift: fetchAndActivate() 결과 처리, Combine 스트림의 에러 매핑 및 기본값(setDefaults) 적용 검증
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift: 버전 문자열 비교 로직(형식/정렬), 강제/선택적 업데이트 분기와 UI/네비게이션 영향
  • src/Projects/BKData/Sources/DataAssembly.swift: 디버그 전용 minimumFetchInterval 설정 의도 및 주입 시점
  • DI 연결(Assembly, SceneDelegate): 새 의존성 주입이 올바르게 연결되는지 확인

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Pull request title clearly describes the main change: implementing force update branching through RemoteConfig, which aligns with the comprehensive changes in the changeset.
Linked Issues check ✅ Passed The pull request successfully implements RemoteConfig variable checking functionality as required by issue #263, including repository, use case, and UI integration for forced and recommended updates.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing RemoteConfig-based app update functionality, with no extraneous modifications detected outside the stated objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BOOK-435-feature/#263

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73db761 and f004f05.

📒 Files selected for processing (1)
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift (4 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeViewController.swift:19-24
Timestamp: 2025-08-08T01:38:59.656Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성(accessibility) 관련 개선사항은 현재 작업 중인 PR에서 즉시 처리하지 않고, 접근성 전용 PR이나 이슈를 별도로 만들어 한번에 처리하는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 68
File: src/Projects/BKDesign/PreviewApp/Sources/View/BKButtonTestViewController.swift:124-133
Timestamp: 2025-07-10T08:21:49.399Z
Learning: doyeonk429는 테스트 전용으로만 사용되는 extension이나 코드는 해당 테스트 파일에 그대로 두는 것을 선호합니다. 실제 프로덕션 코드에서 사용되지 않는 테스트 전용 코드는 별도 파일로 분리하지 않고 테스트 파일 내에 유지하는 것이 그들의 코드 구성 방식입니다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 138
File: src/Projects/BKDesign/Resources/Assets.xcassets/icons/home.imageset/Contents.json:4-14
Timestamp: 2025-08-04T15:20:43.982Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 에셋 파일명이 영어가 아닌 경우(한글, 일본어 등)에는 경고를 받고 싶어하지만, 영어 파일명의 네이밍 컨벤션(예: home.png vs home1.png)은 기능적으로 문제없다면 신경쓰지 않는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/AuthFlow/View/LoginView.swift:43-45
Timestamp: 2025-08-08T01:39:15.620Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성 개선 작업을 별도의 전용 PR이나 이슈에서 일괄 처리하는 것을 선호한다. 개별 기능 구현 PR에서는 접근성 관련 제안을 하지 않고, 접근성 전담 작업에서 한번에 처리하는 방식을 원한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 98
File: src/Projects/BKPresentation/Sources/AuthFlow/View/TermsView.swift:78-85
Timestamp: 2025-07-22T05:37:28.756Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 더미 데이터나 테스트 데이터의 구체적인 내용(예: URL 주소)에 대해서는 리뷰 시 지적하지 않기를 선호한다. 더미 데이터는 임시적이며 실제 기능 구현 시 교체될 예정이므로 URL의 구체적인 주소는 중요하지 않다고 본다.
📚 Learning: 2025-07-11T12:12:48.911Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 79
File: src/Projects/BKPresentation/Sources/MainFlow/Setting/ViewModel/SettingViewModel.swift:78-85
Timestamp: 2025-07-11T12:12:48.911Z
Learning: AppVersionUseCase.execute() returns AnyPublisher<String, Never> where the Failure type is Never, making error handling unnecessary. The app version is retrieved from the main bundle which is always available, and the implementation already handles missing version by defaulting to "-".

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
📚 Learning: 2025-08-06T08:53:16.909Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 147
File: src/Projects/BKData/Sources/Service/AppleLoginDelegateProxy.swift:65-78
Timestamp: 2025-08-06T08:53:16.909Z
Learning: clxxrlove는 Reed-iOS 프로젝트의 Apple 로그인 구현에서 authorizationCode 강제 언래핑 이슈에 대해 현재 구현으로도 문제없다고 판단했다. 초기 구현 단계에서는 기본 기능 동작을 우선시하고 추후 개선할 예정이라는 기존 패턴과 일치한다.

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
📚 Learning: 2025-07-30T11:32:20.533Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 120
File: src/Projects/BKPresentation/Sources/AppCoordinator.swift:31-41
Timestamp: 2025-07-30T11:32:20.533Z
Learning: Reed-iOS 프로젝트의 OnboardingCheckUseCase.execute() 메서드는 AnyPublisher<Bool, Never>를 반환하므로 실패할 수 없도록 설계되었다. Never 타입은 에러가 발생하지 않음을 보장하므로 에러 처리 로직이 불필요하다.

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
🧬 Code graph analysis (1)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (2)
src/Projects/BKCore/Sources/Logger/AppLogger.swift (1)
  • debug (31-42)
src/Projects/BKPresentation/Sources/Common/Constant/AppStoreLinker.swift (1)
  • openAppStore (9-20)
🪛 SwiftLint (0.57.0)
src/Projects/BKPresentation/Sources/AppCoordinator.swift

[Warning] 231-231: TODOs should be resolved ((dyk) : 디자인 파트와 논의 후 subtitle ...)

(todo)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (5)

22-22: 의존성 주입이 올바르게 구현되었습니다

fetchRemoteAppVersionUseCase 의존성이 기존 패턴과 일관되게 추가되었어요.

Also applies to: 32-32, 40-40


94-102: 이전 critical issue가 올바르게 수정되었습니다

권장 업데이트 분기에서 발생했던 모달 프레젠테이션 충돌 문제가 완벽하게 해결되었어요. 이제 presentUpdateSheet(isForced: false)만 호출하고, proceedWithAppFlow()는 다이얼로그가 dismiss된 후 completion handler에서 실행되도록 수정되어 온보딩/로그인 플로우가 정상적으로 진행됩니다.

버전 비교 로직도 명확하게 구현되었습니다:

  • 강제 업데이트: currentVersion < minimumVersion
  • 권장 업데이트: currentVersion < latestVersion (minimum 이상)
  • 정상 진행: 최신 버전 사용 중

70-88: 에러 처리 및 fallback 로직이 적절합니다

Remote Config fetch 실패나 버전 파싱 실패 시 정상 앱 플로우로 진행하는 fallback 전략이 합리적이에요. 네트워크 문제나 Remote Config 이슈로 인해 사용자가 앱을 사용하지 못하는 상황을 방지합니다.


218-253: 강제/권장 업데이트 분기가 명확하게 구현되었습니다

isForced 파라미터를 통해 두 가지 업데이트 시나리오를 깔끔하게 처리하고 있어요:

  • 강제 업데이트: 단일 버튼으로 사용자가 반드시 업데이트하도록 유도
  • 권장 업데이트: "나중에 하기" 옵션으로 사용자 선택권 제공

특히 권장 업데이트의 dismiss completion handler (lines 241-243)가 이전 리뷰에서 지적된 모달 충돌 문제를 정확히 해결했습니다.


90-92: 디버그 로깅이 적절하게 추가되었습니다

버전 비교 과정을 추적할 수 있는 로그가 추가되어 개발 및 디버깅 시 유용하게 활용될 수 있어요.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0af5e0 and 77ba5ed.

📒 Files selected for processing (11)
  • src/Projects/BKData/Project.swift (1 hunks)
  • src/Projects/BKData/Sources/DataAssembly.swift (2 hunks)
  • src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift (1 hunks)
  • src/Projects/BKDomain/Sources/DomainAssembly.swift (1 hunks)
  • src/Projects/BKDomain/Sources/Entity/RemoteAppVersion.swift (1 hunks)
  • src/Projects/BKDomain/Sources/Interface/Repository/RemoteConfigRepository.swift (1 hunks)
  • src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift (1 hunks)
  • src/Projects/BKDomain/Sources/UseCase/DefaultFetchRemoteAppVersionUseCase.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift (4 hunks)
  • src/Projects/Booket/Project.swift (2 hunks)
  • src/Projects/Booket/Sources/SceneDelegate.swift (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeViewController.swift:19-24
Timestamp: 2025-08-08T01:38:59.656Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성(accessibility) 관련 개선사항은 현재 작업 중인 PR에서 즉시 처리하지 않고, 접근성 전용 PR이나 이슈를 별도로 만들어 한번에 처리하는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 68
File: src/Projects/BKDesign/PreviewApp/Sources/View/BKButtonTestViewController.swift:124-133
Timestamp: 2025-07-10T08:21:49.399Z
Learning: doyeonk429는 테스트 전용으로만 사용되는 extension이나 코드는 해당 테스트 파일에 그대로 두는 것을 선호합니다. 실제 프로덕션 코드에서 사용되지 않는 테스트 전용 코드는 별도 파일로 분리하지 않고 테스트 파일 내에 유지하는 것이 그들의 코드 구성 방식입니다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 138
File: src/Projects/BKDesign/Resources/Assets.xcassets/icons/home.imageset/Contents.json:4-14
Timestamp: 2025-08-04T15:20:43.982Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 에셋 파일명이 영어가 아닌 경우(한글, 일본어 등)에는 경고를 받고 싶어하지만, 영어 파일명의 네이밍 컨벤션(예: home.png vs home1.png)은 기능적으로 문제없다면 신경쓰지 않는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/AuthFlow/View/LoginView.swift:43-45
Timestamp: 2025-08-08T01:39:15.620Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성 개선 작업을 별도의 전용 PR이나 이슈에서 일괄 처리하는 것을 선호한다. 개별 기능 구현 PR에서는 접근성 관련 제안을 하지 않고, 접근성 전담 작업에서 한번에 처리하는 방식을 원한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 98
File: src/Projects/BKPresentation/Sources/AuthFlow/View/TermsView.swift:78-85
Timestamp: 2025-07-22T05:37:28.756Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 더미 데이터나 테스트 데이터의 구체적인 내용(예: URL 주소)에 대해서는 리뷰 시 지적하지 않기를 선호한다. 더미 데이터는 임시적이며 실제 기능 구현 시 교체될 예정이므로 URL의 구체적인 주소는 중요하지 않다고 본다.
📚 Learning: 2025-07-11T12:12:48.911Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 79
File: src/Projects/BKPresentation/Sources/MainFlow/Setting/ViewModel/SettingViewModel.swift:78-85
Timestamp: 2025-07-11T12:12:48.911Z
Learning: AppVersionUseCase.execute() returns AnyPublisher<String, Never> where the Failure type is Never, making error handling unnecessary. The app version is retrieved from the main bundle which is always available, and the implementation already handles missing version by defaulting to "-".

Applied to files:

  • src/Projects/BKDomain/Sources/DomainAssembly.swift
  • src/Projects/BKDomain/Sources/Interface/Repository/RemoteConfigRepository.swift
  • src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift
  • src/Projects/BKDomain/Sources/UseCase/DefaultFetchRemoteAppVersionUseCase.swift
  • src/Projects/BKDomain/Sources/Entity/RemoteAppVersion.swift
  • src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift
  • src/Projects/Booket/Sources/SceneDelegate.swift
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
📚 Learning: 2025-07-30T11:32:20.533Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 120
File: src/Projects/BKPresentation/Sources/AppCoordinator.swift:31-41
Timestamp: 2025-07-30T11:32:20.533Z
Learning: Reed-iOS 프로젝트의 OnboardingCheckUseCase.execute() 메서드는 AnyPublisher<Bool, Never>를 반환하므로 실패할 수 없도록 설계되었다. Never 타입은 에러가 발생하지 않음을 보장하므로 에러 처리 로직이 불필요하다.

Applied to files:

  • src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
🧬 Code graph analysis (8)
src/Projects/Booket/Project.swift (1)
src/Tuist/ProjectDescriptionHelpers/TargetDependency+External.swift (1)
  • external (33-35)
src/Projects/BKDomain/Sources/DomainAssembly.swift (1)
src/Projects/BKCore/Sources/DiContainer/DIContainer.swift (1)
  • register (25-46)
src/Projects/BKDomain/Sources/Interface/Repository/RemoteConfigRepository.swift (1)
src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift (1)
  • fetchRemoteAppVersions (22-50)
src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift (1)
src/Projects/BKDomain/Sources/UseCase/DefaultFetchRemoteAppVersionUseCase.swift (1)
  • execute (14-16)
src/Projects/BKDomain/Sources/UseCase/DefaultFetchRemoteAppVersionUseCase.swift (1)
src/Projects/BKData/Sources/Repository/DefaultRemoteConfigRepository.swift (1)
  • fetchRemoteAppVersions (22-50)
src/Projects/BKData/Project.swift (1)
src/Tuist/ProjectDescriptionHelpers/TargetDependency+External.swift (1)
  • external (33-35)
src/Projects/BKData/Sources/DataAssembly.swift (1)
src/Projects/BKCore/Sources/DiContainer/DIContainer.swift (1)
  • register (25-46)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (2)
src/Projects/BKCore/Sources/Logger/AppLogger.swift (1)
  • debug (31-42)
src/Projects/BKPresentation/Sources/Common/Constant/AppStoreLinker.swift (1)
  • openAppStore (9-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (9)
src/Projects/BKData/Project.swift (1)

20-21: LGTM!

FirebaseRemoteConfig 의존성이 올바르게 추가되었습니다.

src/Projects/BKDomain/Sources/Entity/RemoteAppVersion.swift (1)

5-12: LGTM!

Remote Config에서 가져올 앱 버전 정보를 담는 데이터 컨테이너가 명확하게 정의되었습니다. 불변 프로퍼티를 사용한 설계가 적절합니다.

src/Projects/Booket/Sources/SceneDelegate.swift (2)

62-62: LGTM!

fetchRemoteAppVersionUseCase 의존성 주입이 올바르게 추가되었습니다.


71-71: LGTM!

AppCoordinator에 fetchRemoteAppVersionUseCase가 올바르게 전달되고 있습니다.

src/Projects/Booket/Project.swift (2)

34-35: LGTM!

Debug 타겟에 FirebaseRemoteConfig 의존성이 올바르게 추가되었습니다.


80-81: LGTM!

Release 타겟에도 FirebaseRemoteConfig 의존성이 일관되게 추가되었습니다.

src/Projects/BKDomain/Sources/DomainAssembly.swift (1)

73-78: LGTM!

FetchRemoteAppVersionUseCase의 DI 등록이 올바르게 구현되었습니다. RemoteConfigRepository 의존성이 적절하게 주입되고 있습니다.

src/Projects/BKDomain/Sources/Interface/Usecase/FetchRemoteAppVersionUseCase.swift (1)

7-8: LGTM!

Remote Config 조회는 네트워크 오류 등으로 실패할 수 있으므로 Error 타입을 사용한 것이 적절합니다. 기존 AppVersionUseCase가 번들에서 읽어오는 것과 달리, 원격 데이터 조회는 실패 가능성을 고려한 설계가 올바릅니다.

src/Projects/BKDomain/Sources/Interface/Repository/RemoteConfigRepository.swift (1)

6-7: LGTM!

RemoteConfigRepository 프로토콜이 명확하게 정의되었습니다. Use case와 일관된 반환 타입을 사용하고 있습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (2)

218-254: 다이얼로그 생성 코드 중복 고려

강제/권장 업데이트 분기 처리가 올바르게 구현되었고, 특히 권장 업데이트 시 dismiss completion에서 플로우를 진행하도록 수정한 것이 좋습니다.

다만 Line 222-229와 231-245의 다이얼로그 생성 코드에서 title, subtitle이 동일하게 반복됩니다. 공통 부분을 추출하면 유지보수성이 향상될 수 있어요:

 private func presentUpdateSheet(isForced: Bool = true) {
-    var dialog: BKDialog?
+    let config: BKDialog.Configuration
     
     if isForced {
-        dialog = BKDialog(
-            title: "최신 버전이 출시되었습니다",
-            subtitle: "최적의 사용 환경을 위해 업데이트해주세요.",
-            config: .init(
-                leftButtonTitle: "업데이트 하기",
-                leftButtonAction: AppStoreLinker.openAppStore
-            )
+        config = .init(
+            leftButtonTitle: "업데이트 하기",
+            leftButtonAction: AppStoreLinker.openAppStore
         )
     } else {
-        dialog = BKDialog(
-            title: "최신 버전이 출시되었습니다",
-            subtitle: "최적의 사용 환경을 위해 업데이트해주세요.",
-            config: .init(
-                leftButtonTitle: "업데이트 하기",
-                leftButtonAction: AppStoreLinker.openAppStore,
-                rightButtonTitle: "나중에 하기",
-                rightButtonAction: { [weak self] in
-                    guard let self else { return }
-                    self.navigationController.dismiss(animated: true) {
-                        self.proceedWithAppFlow()
-                    }
-                }
-            )
+        config = .init(
+            leftButtonTitle: "업데이트 하기",
+            leftButtonAction: AppStoreLinker.openAppStore,
+            rightButtonTitle: "나중에 하기",
+            rightButtonAction: { [weak self] in
+                guard let self else { return }
+                self.navigationController.dismiss(animated: true) {
+                    self.proceedWithAppFlow()
+                }
+            }
         )
     }
     
-    guard let dialog else { return }
+    let dialog = BKDialog(
+        title: "최신 버전이 출시되었습니다",
+        subtitle: "최적의 사용 환경을 위해 업데이트해주세요.",
+        config: config
+    )
+    
     let dialogViewController = BKDialogViewController(dialog: dialog)
     dialogViewController.isModalInPresentation = true
     DispatchQueue.main.async {
         self.navigationController.present(dialogViewController, animated: true)
     }
 }

251-253: 중복 메인 큐 디스패치 확인

Line 75에서 이미 .receive(on: DispatchQueue.main)으로 메인 스레드에서 실행되고 있는데, Line 251에서 다시 DispatchQueue.main.async를 사용하고 있습니다. 이 추가 디스패치가 의도적인 안전장치가 아니라면 제거해도 될 것 같아요.

     let dialogViewController = BKDialogViewController(dialog: dialog)
     dialogViewController.isModalInPresentation = true
-    DispatchQueue.main.async {
-        self.navigationController.present(dialogViewController, animated: true)
-    }
+    self.navigationController.present(dialogViewController, animated: true)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07105bf and 73db761.

📒 Files selected for processing (1)
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift (4 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeViewController.swift:19-24
Timestamp: 2025-08-08T01:38:59.656Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성(accessibility) 관련 개선사항은 현재 작업 중인 PR에서 즉시 처리하지 않고, 접근성 전용 PR이나 이슈를 별도로 만들어 한번에 처리하는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 68
File: src/Projects/BKDesign/PreviewApp/Sources/View/BKButtonTestViewController.swift:124-133
Timestamp: 2025-07-10T08:21:49.399Z
Learning: doyeonk429는 테스트 전용으로만 사용되는 extension이나 코드는 해당 테스트 파일에 그대로 두는 것을 선호합니다. 실제 프로덕션 코드에서 사용되지 않는 테스트 전용 코드는 별도 파일로 분리하지 않고 테스트 파일 내에 유지하는 것이 그들의 코드 구성 방식입니다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 138
File: src/Projects/BKDesign/Resources/Assets.xcassets/icons/home.imageset/Contents.json:4-14
Timestamp: 2025-08-04T15:20:43.982Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 에셋 파일명이 영어가 아닌 경우(한글, 일본어 등)에는 경고를 받고 싶어하지만, 영어 파일명의 네이밍 컨벤션(예: home.png vs home1.png)은 기능적으로 문제없다면 신경쓰지 않는 것을 선호한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 157
File: src/Projects/BKPresentation/Sources/AuthFlow/View/LoginView.swift:43-45
Timestamp: 2025-08-08T01:39:15.620Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성 개선 작업을 별도의 전용 PR이나 이슈에서 일괄 처리하는 것을 선호한다. 개별 기능 구현 PR에서는 접근성 관련 제안을 하지 않고, 접근성 전담 작업에서 한번에 처리하는 방식을 원한다.
Learnt from: doyeonk429
Repo: YAPP-Github/Reed-iOS PR: 98
File: src/Projects/BKPresentation/Sources/AuthFlow/View/TermsView.swift:78-85
Timestamp: 2025-07-22T05:37:28.756Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 더미 데이터나 테스트 데이터의 구체적인 내용(예: URL 주소)에 대해서는 리뷰 시 지적하지 않기를 선호한다. 더미 데이터는 임시적이며 실제 기능 구현 시 교체될 예정이므로 URL의 구체적인 주소는 중요하지 않다고 본다.
📚 Learning: 2025-07-11T12:12:48.911Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 79
File: src/Projects/BKPresentation/Sources/MainFlow/Setting/ViewModel/SettingViewModel.swift:78-85
Timestamp: 2025-07-11T12:12:48.911Z
Learning: AppVersionUseCase.execute() returns AnyPublisher<String, Never> where the Failure type is Never, making error handling unnecessary. The app version is retrieved from the main bundle which is always available, and the implementation already handles missing version by defaulting to "-".

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
📚 Learning: 2025-08-06T08:53:16.909Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 147
File: src/Projects/BKData/Sources/Service/AppleLoginDelegateProxy.swift:65-78
Timestamp: 2025-08-06T08:53:16.909Z
Learning: clxxrlove는 Reed-iOS 프로젝트의 Apple 로그인 구현에서 authorizationCode 강제 언래핑 이슈에 대해 현재 구현으로도 문제없다고 판단했다. 초기 구현 단계에서는 기본 기능 동작을 우선시하고 추후 개선할 예정이라는 기존 패턴과 일치한다.

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
📚 Learning: 2025-07-30T11:32:20.533Z
Learnt from: clxxrlove
Repo: YAPP-Github/Reed-iOS PR: 120
File: src/Projects/BKPresentation/Sources/AppCoordinator.swift:31-41
Timestamp: 2025-07-30T11:32:20.533Z
Learning: Reed-iOS 프로젝트의 OnboardingCheckUseCase.execute() 메서드는 AnyPublisher<Bool, Never>를 반환하므로 실패할 수 없도록 설계되었다. Never 타입은 에러가 발생하지 않음을 보장하므로 에러 처리 로직이 불필요하다.

Applied to files:

  • src/Projects/BKPresentation/Sources/AppCoordinator.swift
🧬 Code graph analysis (1)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (2)
src/Projects/BKCore/Sources/Logger/AppLogger.swift (1)
  • debug (31-42)
src/Projects/BKPresentation/Sources/Common/Constant/AppStoreLinker.swift (1)
  • openAppStore (9-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (3)

22-22: 새 의존성 추가가 적절합니다

FetchRemoteAppVersionUseCase를 통해 Remote Config 기반 버전 체크로 전환하는 구조가 깔끔하게 구현되었습니다. 의존성 주입 패턴을 일관되게 유지하고 있어요.

Also applies to: 32-32, 40-40


70-105: 업데이트 분기 로직이 올바르게 수정되었습니다

과거 리뷰에서 지적된 critical issue(권장 업데이트 시 proceedWithAppFlow()를 즉시 호출해 로그인/온보딩 플로우가 막히는 문제)가 해결되었습니다. 현재 코드는:

  • Line 97-99: 권장 업데이트 시 다이얼로그만 띄우고 즉시 진행하지 않음
  • Line 238-243: "나중에 하기" 버튼의 dismiss completion에서 플로우 진행

버전 비교 로직(강제 업데이트 vs 권장 업데이트)과 에러 처리도 적절합니다. Remote Config fetch 실패 시 사용자가 앱을 계속 사용할 수 있도록 폴백하는 것이 좋은 선택입니다.


90-92: 디버그 로그 레벨 확인

버전 정보를 디버그 로그로 남기는 것은 개발 중 유용하지만, AppLogger.ui를 사용하고 있네요. AppLogger.debug가 이미 #if DEBUG로 보호되고 있다면 문제없지만, 프로덕션에서 불필요한 로그가 남지 않는지 확인해주세요.

관련 코드에서 AppLogger.debug의 구현을 확인해보니 #if DEBUG로 보호되고 있습니다. 프로덕션에서는 이 로그가 출력되지 않으므로 안전합니다.

@doyeonk429 doyeonk429 force-pushed the BOOK-435-feature/#263 branch from 73db761 to f004f05 Compare November 13, 2025 13:29
@clxxrlove clxxrlove merged commit d92deed into develop Nov 16, 2025
3 checks passed
@clxxrlove clxxrlove deleted the BOOK-435-feature/#263 branch November 16, 2025 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BOOK-435/feat] 강제 업데이트 Remote Config 체크 기능 추가

3 participants