Skip to content

강제업데이트 로직 및 앱피처 모듈을 구성합니다.#314

Merged
dongglehada merged 5 commits intodevfrom
feat/#302-force-update
Apr 8, 2026
Merged

강제업데이트 로직 및 앱피처 모듈을 구성합니다.#314
dongglehada merged 5 commits intodevfrom
feat/#302-force-update

Conversation

@dongglehada
Copy link
Copy Markdown
Member

📌 이슈

✅ 작업 사항

1. 업데이트 체커 기능 구현

  • 강제 업데이트: Major 버전 차이 시 필수 업데이트 요구
  • 선택 업데이트: Minor/Patch 버전 차이 시 선택적 업데이트 제안
  • 7일 스킵 정책: 선택 업데이트는 7일간 스킵 가능, 이후 재알림

2. Clean Architecture 적용

Domain Layer (MLSAppFeatureInterface)

  • Version: 버전 비교 및 파싱을 담당하는 엔티티
  • UpdateStatus: 업데이트 상태를 나타내는 enum (force/optional/none)
  • AppStoreRepositoryProtocol: 앱스토어 조회 인터페이스
  • UpdateSkipRepositoryProtocol: 스킵 정보 관리 인터페이스

Data Layer (MLSAppFeature)

  • AppStoreService: iTunes Search API를 통한 최신 버전 조회
  • UserDefaultsDataSource: UserDefaults 기반 로컬 저장소
  • AppStoreRepository: 앱스토어 데이터 접근 구현체
  • UpdateSkipRepository: 스킵 정보 저장/조회 구현체

Domain Layer (MLSAppFeature)

  • UpdateCheckerUseCase: 업데이트 판단 및 스킵 로직 처리

3. 모듈 구조

MLSAppFeature/
├── Sources/
│   ├── MLSAppFeatureInterface/     # 도메인 인터페이스
│   │   └── Domain/
│   │       ├── Entities/
│   │       └── Repositories/
│   ├── MLSAppFeature/              # 구현체
│   │   ├── Domain/UseCases/
│   │   └── Data/
│   │       ├── Repositories/
│   │       └── DataSources/
│   │           ├── Local/
│   │           └── Remote/
│   └── MLSAppFeatureTesting/       # 테스트 Mock
│       └── Domain/
└── Tests/
    └── MLSAppFeatureTests/         # 테스트 코드
        ├── Domain/
        └── Data/

4. 테스트 작성 (Swift Testing)

  • VersionTests (3개): 버전 파싱 및 비교 로직 검증
  • UpdateCheckerUseCaseTests (9개): 업데이트 판단 및 스킵 로직 검증
    • 강제 업데이트 (major 버전 차이)
    • 선택 업데이트 (minor/patch 버전 차이)
    • 7일 스킵 정책 (유효/만료)
    • 강제 업데이트는 스킵 무시
    • 에러 처리
  • UpdateSkipRepositoryTests (7개): Repository 영속성 및 정책 검증
    • 7일 정책 검증
    • UserDefaults 영속성
    • 커스텀 기간 지원

👀 ETC

  • MicroFeatures + Clean 아키텍처를 적용하였습니다. 처음 구성하는 모듈 구조 이기에 문제 및 개선 사항이 있어보이는 부분이 있다면 코멘트 부탁드립니다!

추후 개발 사항

  • UI 레이어 구현
  • 앱 시작 시 자동 업데이트 체크 기능

@dongglehada dongglehada requested a review from pinocchio22 April 6, 2026 08:02
@dongglehada dongglehada self-assigned this Apr 6, 2026
@dongglehada dongglehada added the feat 새로운 기능을 추가 label Apr 6, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the MLSAppFeature module, which implements an app update checker using the iTunes Search API and local storage for version skipping. The implementation includes a semantic versioning entity, repository patterns, and comprehensive unit tests. Feedback focuses on removing deprecated UserDefaults.synchronize() calls, improving error mapping for decoding failures in the remote service, and cleaning up redundant nonisolated(unsafe) modifiers in classes already marked as @unchecked Sendable.

@pinocchio22
Copy link
Copy Markdown
Contributor

pinocchio22 commented Apr 6, 2026

고생하셨습니다!! 저희가 분리하는 목적인 DataSource–Repository–UseCase 흐름이 잘 반영되어있고 Domain 중심으로 처리하려는 방향을 보니 계층 간 책임을 명확하게 분리한 것으로 보여서 좋네요!!

이전에도 비슷한 문제를 겪었었는데 저는 항상 레포지토리를 구현하다보면 책임의 범위를 명확하게 정하기 힘들더라구요 ㅠㅠ..
UpdateSkipRepository를 보면 버전을 검색 / 저장을 담당함과 동시에 데이터 접근이 아닌 비즈니스 성격의 기간의 유효성 판단도 추가적으로하고 있는것으로 보입니다
이런 경우에 저는 valid관련 UseCase를 따로 뺐었던 경우가 있었던 것 같은데 준영님은 주로 어떤 기준으로 판단하시는지 궁금합니다!!

@dongglehada
Copy link
Copy Markdown
Member Author

고생하셨습니다!! 저희가 분리하는 목적인 DataSource–Repository–UseCase 흐름이 잘 반영되어있고 Domain 중심으로 처리하려는 방향을 보니 계층 간 책임을 명확하게 분리한 것으로 보여서 좋네요!!

이전에도 비슷한 문제를 겪었었는데 저는 항상 레포지토리를 구현하다보면 책임의 범위를 명확하게 정하기 힘들더라구요 ㅠㅠ.. UpdateSkipRepository를 보면 버전을 검색 / 저장을 담당함과 동시에 데이터 접근이 아닌 비즈니스 성격의 기간의 유효성 판단도 추가적으로하고 있는것으로 보입니다 이런 경우에 저는 valid관련 UseCase를 따로 뺐었던 경우가 있었던 것 같은데 준영님은 주로 어떤 기준으로 판단하시는지 궁금합니다!!

@pinocchio22
저는 유효성 검사를 Repository 내부 구현 세부사항으로 봤습니다.
Domain Layer 입장에선 "강제 업데이트 / 패스 / 선택" 이라는 결과값만 받으면 충분하고, 그 값을 도출하기 위해 이미 선택한 값인지는 알 필요가 없다고 생각했어요.

이미지 캐싱으로 비유하면, UseCase는 URL을 넘기고 이미지를 받으면 그만이고 디스크 캐싱인지 메모리 캐싱인지는 Repository 내부 로직인 것처럼요.

저의 기준을 돌아보면 Domain Layer가 최종적으로 무엇을 필요로 하는가? 였던 것 같아요.
Domain은 가장 추상화된 비즈니스 로직만 알면 되고, 구체적인 구현 방식은 내려보내는 방향으로 생각했습니다.

@dongglehada dongglehada merged commit 055ecd2 into dev Apr 8, 2026
2 checks passed
@dongglehada dongglehada deleted the feat/#302-force-update branch April 8, 2026 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새로운 기능을 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants