Skip to content

[Refactor] SwiftUI기반 네비게이션 마이그레이션#287

Open
JinUng41 wants to merge 8 commits into
developfrom
refactor/LIVD-425-navigation
Open

[Refactor] SwiftUI기반 네비게이션 마이그레이션#287
JinUng41 wants to merge 8 commits into
developfrom
refactor/LIVD-425-navigation

Conversation

@JinUng41

Copy link
Copy Markdown
Contributor

PULL REQUEST

📄 작업 내용

  • Login/User/Home/Search/Concert/Setlist/Song 7개 Feature의 화면 전환을 UIKit Coordinator에서 SwiftUI NavigationStack + Router로 전환
  • 다른 Feature로 진입(Home/Search → Concert) 시 화면 stack 하나로 통합
  • *Coordinator 클래스 5개, EnvironmentValues 5개, *ContentView 래퍼 4개, 자식 ConcertCoordinator 1개 제거
  • *CoordinatorView 5개 새로 선언 (Login/User/Home/Search/Concert는 stack 없이 부모와 공유)
  • 모달은 각 화면에서 .sheet(isPresented:) / .fullScreenCover(isPresented:)로 자체 처리
  • docs/rules/architecture.md의 화면 전환 규칙을 새 패턴으로 갱신

💻 주요 개선 사항

1. UIKit 의존성 제거

  • SwiftUI 화면을 UIKit에 감싸던 UIViewControllerRepresentable 래퍼 5개와 UINavigationControllerDelegate 기반 tab bar 숨김 로직을 모두 제거.
  • ConcertCoordinator에서 SwiftUI 화면을 UIHostingController로 감싸던 코드(buildViewController)도 제거. SwiftUI 네이티브 API만 사용.

2. 코드 감소

  • 화면 전환 인프라(UIKit Coordinator + EnvironmentValues + ContentView) 일괄 제거로 UIKit → SwiftUI 전환에도 코드 양이 감소.
  • navigation 인프라 변경: -993줄 / +581줄 = 약 -412줄 순감. 예: HomeContentView(105줄), HomeCoordinator(133줄), ConcertCoordinator(118줄), UserCoordinator(97줄) 등 UIKit 의존 클래스가 통째로 삭제됨.

3. 자식 화면 (Concert) 패턴

Concert 6개 view에서 concertCoordinator 환경 의존 제거. onTicketSiteReturn 메커니즘을 init 클로저로 변경하여 3개 자식 view에 전달.

3-1. 왜 자식 화면(Concert)은 stack 없이 CoordinatorView + 선언형 NavigationLink인가

WWDC22 "The SwiftUI cookbook for navigation" 세션을 통해 NavigationLink(value:)로 넘긴 값이 가장 가까운 NavigationStack의 path에 추가된다는 것을 학습. 별도 stack 없이 부모의 NavigationStack에 자연스럽게 push됨.

해결

stack 없이 ConcertCoordinatorView만 두고, 선언형 NavigationLink(value:) 채택.

장점:

  1. 중첩 회피: stack 하나로 통일. 뒤로 가기가 한 stack에서 자연스럽게 동작.
  2. 하나의 뒤로 가기 흐름: Home → Concert → Setlist → Song 의 back이 부모 stack의 단계별 pop으로 이어짐.
  3. 모듈 간 연결 (SetlistDetailContainerView): SetlistFeatureConcertRoute를 import하지 못하므로 closure 인터페이스(onPlaySong) 유지. ConcertFeature의 wrapper가 @State pendingSong + .navigationDestination(item:)로 부모 stack에 push. 모듈 독립성 유지.
  4. 선언형 navigation: NavigationLink(value:)가 view body에 선언되어 화면 전환 관계가 한눈에 보임.

7. 화면 전환 흐름 (Concert 진입)

sequenceDiagram
    actor User
    participant HomeView
    participant HomeRouter
    participant NavStack as Home NavigationStack
    participant ConcertCoord as ConcertCoordinatorView (view-only)
    participant ConcertView
    participant SetlistContainer as SetlistDetailContainerView
    participant SetlistView

    User->>HomeView: 콘서트 카드 탭
    HomeView->>HomeRouter: homeRouter.push(.concertDetail(id:1))
    HomeRouter->>NavStack: path.append(.concertDetail)
    NavStack->>ConcertCoord: navigationDestination(for: HomeRoute) → case .concertDetail
    ConcertCoord->>ConcertView: root view 렌더링

    Note over ConcertCoord: Router 없음, NavigationStack 없음<br/>navigationDestination(for: ConcertRoute) 등록

    User->>ConcertView: setlist 카드 탭
    ConcertView->>NavStack: NavigationLink(value: .setlistDetail)
    NavStack->>ConcertCoord: case .setlistDetail 매칭
    ConcertCoord->>SetlistContainer: 렌더링
    SetlistContainer->>SetlistView: onPlaySong 클로저 전달

    User->>SetlistView: 곡 탭
    SetlistView->>SetlistContainer: onPlaySong(song) → pendingSong = song
    SetlistContainer->>NavStack: .navigationDestination(item: $pendingSong) → SongLyricsView
    NavStack->>SetlistView: pop (back)
    User->>ConcertView: back → NavStack: pop → HomeView
Loading

📚 참고자료

  • Apple Developer — The SwiftUI cookbook for navigation (WWDC22)
  • 이번 브랜치에서 작성/보관된 문서
    • docs/archives/adr-001-navigationstack-migration.md
    • docs/archives/LIVD-425-login-navigationstack-migration.md
    • docs/archives/LIVD-425-user-navigationstack-migration.md
    • docs/archives/LIVD-425-concert-setlist-song-navigationstack-migration.md
    • docs/archives/LIVD-425-home-navigationstack-migration.md
    • docs/archives/LIVD-425-search-navigationstack-migration.md

👀 기타 더 이야기해볼 점

  • 알림 수신 후 특정 화면으로 진입하는 시나리오만 점검부탁드립니다. (딥링크 처리)

🔗 연결된 이슈

  • Resolved: LIVD-425

JinUng41 added 8 commits June 15, 2026 16:42
- Router.swift: NavigationStack 관리를 위한 공용 Router 클래스 추가
- LoginCoordinatorView.swift: NavigationStack 기반의 로그인 화면 전환 뷰 구현
- LoginRouter.swift: 로그인 경로 이동을 담당하는 전용 라우터 정의
- LoginRoute.swift: NavigationStack 호환을 위해 Hashable 채택
- LoginView.swift: EnvironmentObject를 통한 라우터 주입 방식으로 전환
- AppRootView.swift: 로그인 진입점을 LoginCoordinatorView로 교체
- LoginCoordinator.swift, LoginContentView.swift, EnvironmentValues+LoginCoordinator.swift: 기존 UIKit 기반 코드 삭제
- LIVD-425-login-navigationstack-migration.md: 네비게이션 마이그레이션 문서 추가
기존 UIKit 기반의 Coordinator 패턴에서 SwiftUI 전용 NavigationStack 방식으로 전환하여 유저 기능 내비게이션 구조를 개선했습니다.

- LivithMainTabView.swift: UserContentView를 UserCoordinatorView로 교체
- UserCoordinatorView.swift: NavigationStack을 활용한 신규 코디네이터 뷰 구현
- UserRouter.swift, UserRoute.swift: 경로 관리 및 내비게이션 제어를 위한 라우터 추가
- UserView.swift, SettingView.swift, DeleteUserView.swift 등: 기존 코디네이터 의존성을 Router로 마이그레이션
- EnvironmentValues+UserCoordinator.swift, UserCoordinator.swift, UserContentView.swift: 불필요해진 기존 내비게이션 로직 삭제
- LIVD-425-user-navigationstack-migration.md: 마이그레이션 상세 내용 문서화
기존 UIKit 기반의 ConcertCoordinator를 제거하고 SwiftUI NavigationStack 기반의 네비게이션 구조로 전환했습니다.

- ConcertCoordinator.swift: 기존 UIKit 기반 코디네이터 삭제
- ConcertCoordinatorView.swift: NavigationStack을 사용하는 신규 코디네이터 뷰 구현
- ConcertRoute.swift: Hashable 프로토콜 채택 및 네비게이션 경로 최적화
- SetlistDetailContainerView.swift: 셋리스트 상세 및 곡 가사 화면 전환을 위한 컨테이너 추가
- ConcertView.swift, MerchandiseDetailView.swift: NavigationStack 구조에 맞게 네비게이션 로직 수정
- adr-001-navigationstack-migration.md: 네비게이션 마이그레이션 관련 설계 문서 추가 및 업데이트
- LivithMainTabView.swift: 기존 HomeContentView를 HomeCoordinatorView로 교체 및 탭 바 숨김 처리 방식 변경
- HomeContentView.swift, HomeCoordinator.swift, EnvironmentValues+HomeCoordinator.swift: 기존 UIKit 기반 코디네이터 관련 파일 삭제
- HomeCoordinatorView.swift, HomeRoute.swift, HomeView.swift: NavigationStack 및 NavigationPath를 활용한 새로운 내비게이션 구조 구현
- RecommendedConcertGridView.swift, InterestConcertListView.swift, InterestConcertSettingView.swift, ArtistUpdateView.swift, GenreUpdateView.swift: 새로운 코디네이터 패턴에 맞춰 화면 이동 로직 수정
- LIVD-425-home-navigationstack-migration.md: 홈 플로우 마이그레이션 상세 내용 문서화
검색 플로우를 기존 UIKit 기반 UINavigationController에서 SwiftUI NavigationStack으로 마이그레이션합니다. Router 패턴을 도입하여 네비게이션 로직을 통합 관리하고 레거시 코드를 제거합니다.

- LivithMainTabView.swift: SearchContentView를 SearchCoordinatorView로 교체 및 탭 바 제어 로직 수정
- SearchCoordinatorView.swift: NavigationStack과 Router를 활용한 신규 검색 코디네이터 구현
- SearchRoute.swift: Hashable 채택 및 콘서트 상세 화면 이동 경로 추가
- ExploreView.swift, SearchView.swift: Router를 통한 네비게이션 이동 방식으로 변경
- SearchCoordinator.swift, SearchContentView.swift, EnvironmentValues+SearchCoordinator.swift: 기존 UIKit 기반 코드 및 환경 변수 삭제
- LIVD-425-search-navigationstack-migration.md: 검색 플로우 마이그레이션 관련 문서 업데이트
- ConcertView.swift: ConcertStore를 @ObservedObject에서 @StateObject로 변경하여 뷰 재렌더링 시 Store가 다시 생성되는 현상 방지
- SongLyricsView.swift: 가사 시트 상태 관리 방식을 @State로 전환하고, 가사 시트와 정보 제보 시트 간의 중첩 방지 및 순차적 전환 로직 구현
- adr-001-navigationstack-migration.md: SwiftUI NavigationStack 기반 마이그레이션 결정 사항(ADR) 문서 추가
- architecture.md: 네비게이션 패턴을 Router + NavigationStack 중심으로 갱신 및 관련 설계 원칙 업데이트
@JinUng41 JinUng41 requested a review from youz2me June 16, 2026 13:43
@JinUng41 JinUng41 self-assigned this Jun 16, 2026
@linear

linear Bot commented Jun 16, 2026

Copy link
Copy Markdown

LIVD-425

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant