Skip to content

[Work 30] DIContainer를 도입하고 미연결 화면 전환 로직을 구현했습니다. - #19

Open
snughnu wants to merge 6 commits into
developfrom
WORK-30
Open

[Work 30] DIContainer를 도입하고 미연결 화면 전환 로직을 구현했습니다.#19
snughnu wants to merge 6 commits into
developfrom
WORK-30

Conversation

@snughnu

@snughnu snughnu commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

JIRA

📝 작업 내용

📌 요약

  • register/resolve 방식의 DIContainer를 도입해,
    각 화면이 직접 생성하던 Mock Repository를 한 곳에서 조립하도록 정리했습니다.
  • 앱 정보를 제외한 print나 TODO로만 남아 있던 화면 전환 로직을 모두 실제 이동으로 연결했습니다.

🔍 상세

1. DIContainer 도입

  • 문제 상황
    • 지금까지 각 ViewController가 MockXXXRepository()를 화면 안에서 직접 생성하고 있었습니다.
    • 같은 Mock Repository가 여러 화면에 중복 생성되어 있어, 실제 구현체로 바꾸려면 이 화면들을 전부 찾아 하나씩 고쳐야 하는 상태였습니다.
  • 해결 방법
    • DIContainer
      • register(_:factory:) / register(_:instance:) / resolve(_:)를 제공하는 컨테이너입니다.
      • factory 등록은 resolve 호출마다 새 인스턴스를 생성하고, instance 등록은 항상 같은 인스턴스를 반환합니다.
      • 등록되지 않은 타입을 resolve하면 즉시 fatalError로 크래시합니다(등록 누락을 개발 중 바로 드러내기 위함).
    • AppDIContainer+Register
      • 앱이 쓰는 Repository들을 등록하는 지점입니다.
      • 이후 Mock → 실제 구현체로 바꿀 때 이 등록부 한 곳만 고치면 됩니다.
      • CoreLocationRepository
    • AppDelegate에서 앱 시작 시 DIContainer.shared.registerDependencies()를 호출합니다.
    • 모든 화면에서 MockXXXRepository() / CoreLocationRepository()를 직접 생성하던 부분을 DIContainer.shared.resolve(...)로 교체했습니다.

2. 미연결 화면 전환 로직 연결

  • 문제 상황
    • Home의 예정된 약속 카드 탭, 약속 참여하기, Chat의 지도 버튼/공유 위치 보기, 약속 목록 카드의 대화하기/지도보기, 약속 경로 화면의 "경로 변경", 약속 생성 완료 후 확인 버튼 등 print나 TODO 주석으로만 남아 있고 실제 화면 전환으로 이어져 있지 않았습니다.
  • 해결 방법
    • 참여 코드로 약속을 찾는 기능 자체가 없어서 새로 추가했습니다.
      • AppointmentDetailRepositoryfetchAppointment(code:completion:)를 추가하고, MockAppointmentDetailRepository는 정해진 코드(MOCK1234)만 성공, 나머지는 AppError.notFound로 실패하도록 구현했습니다.
      • 코드 조회 전용 JoinAppointmentUseCase를 신규 작성했습니다(ID 조회용 GetAppointmentDetailUseCase와 목적이 달라 UseCase는 분리, Repository는 공유).
    • HomeViewController
      • 예정된 약속 카드 탭 시 FetchAppointmentInfoUseCase로 약속 정보를 조회해 Chat으로 이동하도록 연결했습니다.
      • 약속 참여하기 시트는 JoinAppointmentUseCase로 코드를 검증해 성공 시 Chat으로 이동, 실패 시 알림을 띄우도록 연결했습니다.
      • 붙여넣기 버튼이 클립보드 값을 코드 입력창에 채우도록 연결했습니다.
    • ChatViewController
      • 지도 버튼과 채팅 버블의 "위치 보기" 버튼을 눌렀을 때 약속 경로 화면(AppointmentRouteViewController)을 열도록 연결했습니다.
      • 공유 위치/장소의 좌표를 화면까지 전달하기 위해 ChatBubbleItem에 좌표 필드를 추가했습니다.
    • AppointmentListViewController / PastAppointmentListViewController
      • 카드의 대화하기/지도보기 버튼을 각각 Chat, 약속 경로 화면으로 연결했습니다.
    • AppointmentRouteViewController / AppointmentRouteViewModel
      • "경로 변경" 버튼을 눌렀을 때 목적지 정보를 함께 전달해 길찾기 화면(RouteSearchViewController)을 열도록 연결했습니다.
    • AppointmentCreationViewController
      • 약속 생성 완료 확인 카드의 확인 버튼을 눌렀을 때, 생성 화면을 Chat 화면으로 교체(뒤로가기 시 생성 화면으로 돌아가지 않도록)하도록 연결했습니다.

💬 리뷰 노트

1. register/resolve 방식의 DIContainer를 선택한 이유

  • Swinject 등 서드파티 DI 라이브러리
    • 의존성 추가 대비, 지금 프로젝트 규모(화면 10여 개)에서 얻는 이점이 크지 않다고 판단해 제외했습니다.
  • AppDIContainer.makeXXXViewController() 형태의 Factory 메서드
    • 반환 타입을 컴파일 타임에 강제할 수 있어 register/resolve보다 안전성은 더 높습니다.
    • 다만 이 방식은 Container가 "어떤 화면에 어떤 조합이 필요한지"까지 알아야 합니다.
    • 이후 Coordinator 등 화면 전환 로직을 도입하면 조립 지식이 Container와 Coordinator 양쪽에 나뉘어 중복될 여지가 있다고 봤습니다.
  • register/resolve 방식 (채택)
    • Container의 책임을 "타입 하나를 어떻게 만드는지"로 한정하고, "무엇을 어떤 조합으로 만들지"에 대한 조립 지식은 이후 도입할 Coordinator 쪽에 남겨둘 수 있다는 점이 가장 컸습니다.
    • 타입 캐스팅 실패나 등록 누락이 런타임에야 드러난다는 단점이 있지만, 등록 누락 시 즉시 fatalError로 크래시하도록 만들어 개발 중 바로 드러나게 했습니다.

2. UseCase는 등록하지 않고 Repository만 등록

  • 문제는 "Mock Repository를 실제 구현체로 교체하기 어렵다"는 것이고, 이건 Repository만 등록해도 충분히 해결됐습니다.
  • UseCase까지 등록도 생각해봤는데, Mock/실제 교체라는 목적과는 관련이 없어 등록하지 않았습니다.

3. 조립과 화면 전환이 여전히 ViewController 안에 있음

  • 이번 PR로 "Mock Repository가 여러 화면에 중복 생성되던 문제"와 "화면이 안 이어져 있던 문제"는 해결했지만, ViewController가 UseCase/ViewModel을 직접 조립하고 다음 화면 전환까지 스스로 담당하는 구조 자체는 그대로 남아 있습니다.
  • 다음 작업에서 위 문제를 해결할 방법을 검토할 계획입니다.

@snughnu
snughnu requested a review from sangYuLv August 26, 2026 14:53
@snughnu snughnu self-assigned this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant