- App 이
Sentry와SentrySwiftUI를 동시에 직접 링크하지 않도록 정리했다. -all_load를 제거해 Sentry Objective-C class 가 앱 바이너리에 중복 로드되는 원인을 줄였다.- Sentry 관련 package product 는 현재 안전한 static 설정을 유지한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
ModuleTarget기준으로interface,implementation,testing타깃 경로를 표현할 수 있게 했다.Project.makeMicroFeature를 추가해<Feature>Interface,<Feature>,<Feature>Testing,<Feature>Tests타깃을 같은 규칙으로 만들 수 있게 했다.- Joongna 스타일 호출을 위해
Project.configure(moduleType: .feature(name: ...))wrapper 를 추가했다. Auth,Battle,Chat,Notification,Splash,Web에 Interface/Testing placeholder target 을 추가했다.- Presentation umbrella 가 전체 feature implementation 을 조립하도록 확장했다.
검증:
./tuisttool generate성공.
- 홈 bundle 응답의
newNotice값이 이미 읽음 처리된 notification badge 를 다시 살리지 않도록 reducer 갱신 경로를 정리했다. - 관련 reducer test 를 추가했다.
검증:
- 전체 통합 시나리오 검증은 아직 남아 있다.
- 기존
MainTabCoordinator의 동작을 보존해AppMainTabCoordinator로 App 타깃에 옮겼다. - 기존
MainTabView의 탭 UI 조립을AppMainTabView로 App 타깃에 옮겼다. AppReducer/AppView는 더 이상MainTabCoordinator/MainTabView를 직접 사용하지 않는다.Presentationumbrella 가Home,Hifi,Battle,Profile을 re-export 하도록 확장했다.- App target 은 직접 feature implementation 을 추가로 의존하지 않고, 기존처럼 Presentation umbrella 를 통해 조립한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- MainTab 모듈에서 기존
MainTabCoordinator/MainTabView구현을 제거했다. MainTabInterface,MainTab,MainTabTestingplaceholder target 구조로 낮췄다.- MainTab implementation 이 더 이상
Home,Hifi,Battle,Profileimplementation 을 직접 의존하지 않는다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
ProjectModuleType을ModuleType으로 정리하고, App / feature / 일반 module 을 모두Project.configure(...)로 생성하도록 맞췄다.- Presentation feature 는 문자열 기반
.feature(name: "Home")대신 카탈로그 기반.feature(.Home)형태로 변경했다. - App, Domain, Data, Network, Shared, Presentation umbrella 의
Project.swift도makeModule/makeAppModule직접 호출 대신Project.configure를 사용한다. Home,Hifi,Profile에Interface/Testingplaceholder target 을 추가해 모든 Presentation feature 가 micro-feature target 구조를 갖게 했다.WebInterface,NotificationInterface에 route/delegate 계약의 첫 타입을 추가했다. 구현 전환은 아직 하지 않고, 다음 단계에서 implementation 직접 의존 제거에 사용한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- Joongna 구조처럼
ModuleType.swift,Project+Template.swift,Project+App.swift,Project+Feature.swift,Project+Module.swift,Project+Target.swift로 helper 책임을 분리했다. Project+Template.swift는Project.configure(...)단일 진입점만 유지한다.- App / 일반 module / feature target 생성 로직은 각각 별도 파일로 이동했다.
- 기존 Picke 설정인
bundleId,settings,resources,scripts,hasTests,schemes전달 방식은 그대로 보존했다.
검증:
./tuisttool generate성공.
- App 타깃에
AppAuthCoordinator/AppAuthCoordinatorView를 추가했다. - 로그인 / 온보딩 / 약관 WebView 라우팅 동작은 App 조립 레이어에서 그대로 처리한다.
AppReducer/AppView는 인증 플로우에서AuthCoordinator대신AppAuthCoordinator를 사용한다.- Auth 모듈의
AuthCoordinator는LoginFeature/OnBoardingFeature만 보도록 낮췄다. - Auth 모듈의
.Presentation(.Web, .implementation)의존을 제거했다. - App 조립 레이어에서
LoginView를 생성할 수 있도록LoginView.init(store:)를 public 으로 열었다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- App 타깃에
AppProfileCoordinator/AppProfileCoordinatorView를 추가했다. - 마이페이지의 알림 목록 / 약관 WebView / 탈퇴 화면 라우팅 동작은 App 조립 레이어에서 그대로 처리한다.
AppMainTabCoordinator/AppMainTabView의 myPage 탭은ProfileCoordinator대신AppProfileCoordinator를 사용한다.- Profile 모듈의
ProfileCoordinator는 Profile 내부 화면만 보도록 낮췄다. - Profile 모듈의
.Presentation(.Web, .implementation)/.Presentation(.Notification, .implementation)의존을 제거했다. - App 조립 레이어에서 사용할 수 있도록 Presentation umbrella 가 Notification 구현도 re-export 한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- App 타깃에
AppHomeCoordinator/AppHomeCoordinatorView를 추가했다. - App 타깃에
AppHifiCoordinator/AppHifiCoordinatorView를 추가했다. - App 타깃에
AppBattleCoordinator/AppBattleCoordinatorView를 추가했다. - Home / Hifi / Battle 탭에서 Chat, ChatRoom, Notification 으로 이동하는 기존 라우팅 동작은 App 조립 레이어에서 그대로 처리한다.
AppMainTabCoordinator/AppMainTabView는 Home / Hifi / Battle 탭도 App 조립 코디네이터를 사용한다.- Home / Hifi / Battle 모듈의 coordinator 는 각 모듈 내부 루트 화면만 보도록 낮췄다.
- Home / Hifi / Battle 모듈의 Chat / Notification implementation 의존을 제거했다.
- App 조립 레이어에서 사용할 수 있도록 Presentation umbrella 가 Chat 구현도 re-export 한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
ChatInterface에ChatRoute,ChatRoomRoute,ChatDelegate,ChatRoomDelegate를 추가했다.NotificationInterface에NotificationRoute를 추가했다.WebReducer.State,NotificationCoordinator.State,ChatCoordinator.State,ChatRoomFeature.State가 Interface route 로 초기화될 수 있게 했다.- App 조립자는 Web / Notification / Chat 구현 State 를 primitive 값 대신 Interface route 계약으로 생성한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- Presentation feature catalog 를
PresentationFeatureModule한 곳으로 모았다. .Presentation(...)dependency/path helper 를ProjectTemplatePlugin으로 옮겨Project.configure(.feature(...))와 같은 catalog 를 사용하게 했다.DependencyPlugin의ModulePath.Presentations/ Presentation 전용 path/dependency helper 를 제거했다.- App 스킴 생성 규칙을
Scheme.appSchemes(appName:)helper 로 옮겨 AppProject.swift에서 로컬 함수를 제거했다. - App / 일반 module / feature implementation / Interface / Testing / Tests target 을
buildableFolders기반으로 생성한다. - Feature Interface target 은
Interface, Testing target 은Testing, Tests target 은Tests루트 폴더를 buildable folder 로 사용한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
WebReducer.Action을 구현 전용.backToRoot액션에서.delegate(WebDelegate)로 전환했다.WebView의 뒤로가기 버튼은WebDelegate.backToRoot를 발행한다.AppAuthCoordinator/AppProfileCoordinator는 Web 구현 액션명이 아니라WebDelegate.backToRoot를 처리한다.NotificationCoordinator.Action.delegate는NotificationDelegate를 직접 사용한다.ChatCoordinator.Action.delegate는ChatDelegate를 직접 사용한다.ChatRoomFeature.Action.delegate는ChatRoomDelegate를 직접 사용한다.
검증:
./tuisttool generate성공.xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build성공.
- 빌드된
Picke.app을 iOS 26.3 iPhone 13 mini 시뮬레이터에 설치했다. io.Picke.cobundle id 로 앱 launch 를 확인했다.- launch 후 홈 화면 스크린샷을 확인했다.
검증:
xcrun simctl install 1A3C0DA4-CE3F-4F0C-8E8D-149F6BEE55AA .../Picke.app성공.xcrun simctl launch 1A3C0DA4-CE3F-4F0C-8E8D-149F6BEE55AA io.Picke.co성공. PID43924.xcrun simctl io ... screenshot /private/tmp/picke-launch-smoke.png성공.
현재 feature 모듈의 직접 implementation 의존:
없음
남은 정리:
- 실제 시뮬레이터에서 각 탭의 Chat / Notification / Web 이동을 수동 smoke test 한다.
- 알림함 전체 읽음 후 홈 상단 badge 가 사라지는지 실제 계정/데이터로 확인한다.
완료 조건:
- feature implementation 이 다른 feature implementation 을 직접 import 하지 않는다.
- 기존 navigation/deeplink/로그아웃/알림 badge 동작이 유지된다.
- 각 feature 의 delegate/output contract 를 App 조립자에서 처리할 수 있는 형태로 더 세분화한다.
완료 조건:
Auth,Profile의 Web/Notification 구현 조립은 App 레이어에만 존재한다.Home,Hifi의 Notification 이동 계약은NotificationInterface에 있다.Battle,Home,Hifi의 Chat 이동 계약은ChatInterface에 있다.
각 단계마다 아래 순서로 검증한다.
./tuisttool generate
xcodebuild -workspace Picke.xcworkspace -scheme Picke-Debug -configuration Debug -destination 'generic/platform=iOS Simulator' build동작 변경 가능성이 있는 reducer 변경은 target test 를 먼저 추가하거나 갱신한다.