-
Notifications
You must be signed in to change notification settings - Fork 0
Module Structure
JEONG edited this page Aug 24, 2026
·
2 revisions
Tuist 기반
UMCApp/모듈 구조와 의존성 방향. 빌드 명령은 Build & Run 참고.
| 축 | 형태 | 상태 |
|---|---|---|
UMCApp/ |
Tuist | 활성 — 모든 신규·유지보수 작업 대상 |
AppProduct/ |
xcodeproj | 레거시, v2.2.0 동결 (열람/참고 전용) |
UMCApp/
├── Makefile # 빌드/생성 래퍼 (mise exec 기반)
├── MAKEFILE_GUIDE.md # 팀원용 사용 가이드
├── mise.toml # tuist 버전 고정 (4.155.0)
├── Project.swift # 앱 타겟 정의 (com.umc.product)
├── Workspace.swift # 워크스페이스 (., Core/*, Features/*, Widget, Watch)
├── Tuist.swift # Tuist 시스템 설정
├── Scripts/verify-secrets.sh # 시크릿 누락 가드 (Release 빌드 실패)
├── Secrets/ # xcconfig 기반 환경/시크릿 주입
├── Tuist/
│ ├── Package.swift # SPM 외부 의존성
│ └── ProjectDescriptionHelpers/
│ ├── Project+Core.swift # Core 모듈 헬퍼
│ ├── Project+Feature.swift # Feature 모듈 헬퍼 (3 타겟 + 테스트)
│ ├── Project+WidgetExtension.swift
│ ├── Project+WatchApp.swift
│ └── Settings+Recommended.swift # 권장 빌드 설정 · 버전 · 서명
├── Core/ # 11개 공유 인프라 모듈
│ ├── Foundation/ # UMCFoundation — Config, 에러 타입, Loadable,
│ │ # AlertPrompt, 위치(LocationManager/Geofence),
│ │ # Date/String 확장, Flexible 디코딩 헬퍼 [iOS+watchOS]
│ ├── Domain/ # CoreDomain — 교차 도메인(Member/Authorization/Post)
│ ├── Network/ # CoreNetwork — Moya, 소셜 SDK, Keychain, STOMP 실시간
│ ├── DI/ # CoreDI — DIContainer, Environment 주입
│ ├── Routing/ # CoreRouting — NavigationTab, PathStore
│ ├── DesignSystem/ # CoreDesignSystem — 색상/타이포/레이아웃 토큰, 폰트
│ ├── UIComponents/ # CoreUIComponents — 공용 컴포넌트 (Kingfisher, MapKit, TipKit)
│ ├── Photo/ # CorePhoto — 사진 선택 프로토콜
│ ├── NearbyExchange/ # CoreNearbyExchange — MPC 전송 + NearbyInteraction 거리
│ ├── WatchConnectivity/ # CoreWatchConnectivity — iOS ↔ watchOS [iOS+watchOS]
│ └── WidgetShared/ # CoreWidgetShared — Widget-App 공유 모델
├── Features/ # 9개 기능 모듈 (각 Domain/Data/Presentation 3 타겟)
│ ├── Activity/ # 출석·스터디·커리큘럼·멤버 관리
│ ├── Auth/ # 소셜/이메일 로그인, 회원가입, 비밀번호
│ ├── Badge/ # 배지
│ ├── BusinessCard/ # 전자명함 · 명함첩 · 근거리 교환 · QR
│ ├── Community/ # 스레드(채팅)·게시물, 온디바이스 AI 요약/분류
│ ├── Home/ # 홈 대시보드·일정·출석 (CoreML 분류 모델 포함)
│ ├── Maintenance/ # 원격 점검(킬스위치)·강제 업데이트 (RemoteConfig)
│ ├── MyPage/ # 마이페이지·프로필
│ └── Notice/ # 공지 (The Ping)
├── UMCAppWidget/ # Widget Extension (com.umc.product.widget)
└── UMCWatchApp/ # watchOS Companion App (com.umc.product.watchkitapp)
App Target (UMCApp)
↓
Feature Presentation (자기 Domain + CoreDesignSystem + CoreUIComponents + UMCFoundation)
↓
Feature Domain (UMCFoundation [+ CoreDomain])
Feature Data (자기 Domain + CoreNetwork + UMCFoundation)
↓
Core Modules (Foundation / Domain / Network / DI / Routing / DesignSystem / …)
↓
External Packages (Moya · Kingfisher · Kakao SDK · GoogleSignIn · Firebase)
-
Core → Feature 의존 금지.
CoreRouting이 타입 소거NavigationPath를 쓰는 이유가 이것입니다 (Architecture › PathStore 참고). -
Feature → Feature 의존은 Domain 타겟까지만 허용합니다. 예:
MyPageDomain이AuthDomain/BadgeDomain/CommunityDomain/BusinessCardDomain을 참조. 예외적으로HomePresentation이ActivityPresentation을 링크합니다(홈에서 출석 화면 직접 진입). -
두 개 이상의 Feature가 실제로 공유하는 도메인만
CoreDomain으로 승격합니다. -
staticFramework는 Compile Sources 산출물이 소비 타겟까지 전파되지 않습니다. 런타임 리소스(CoreML.mlmodel등)는dataResources로 리소스 번들에 명시해야 합니다. (예:Features/Home/Data/Sources/MLModels/**—NoticeClassifierML,ScheduleListClassifierML)
| 타겟 | Product Type | Bundle ID 패턴 | Sources |
|---|---|---|---|
{Name}Domain |
.staticFramework |
dev.umc.feature.{name}.domain |
Domain/Sources/** |
{Name}Data |
.staticFramework |
dev.umc.feature.{name}.data |
Data/Sources/** |
{Name}Presentation |
.staticFramework |
dev.umc.feature.{name}.presentation |
Presentation/Sources/** |
{Name}{Layer}Tests |
.unitTests |
…{layer}.tests |
{Layer}/Tests/** |
테스트 타겟은 includesDomainTests / includesDataTests / includesPresentationTests
플래그로 레이어별로 켭니다. 메인 타겟은 자동으로 의존성에 포함됩니다.
// Core 모듈 (단일 staticFramework + 옵션 테스트)
coreProject(
name: "CoreNetwork",
bundleIdSuffix: "network",
dependencies: [
.project(target: "UMCFoundation", path: .relativeToRoot("Core/Foundation")),
.external(name: "Moya"),
],
includesTests: true
)
// watchOS 공유 모듈은 destinations / deploymentTargets 를 넘긴다
coreProject(
name: "CoreWatchConnectivity",
bundleIdSuffix: "watchconnectivity",
destinations: [.iPhone, .appleWatch],
deploymentTargets: .multiplatform(iOS: "26.4", watchOS: "26.4"),
dependencies: [.sdk(name: "WatchConnectivity", type: .framework, status: .required)]
)
// Feature 모듈 (Domain/Data/Presentation 3 타겟 자동 생성)
featureProject(
name: "Maintenance",
dataExtraDependencies: [
.external(name: "FirebaseCore"),
.external(name: "FirebaseRemoteConfig"),
],
presentationExtraDependencies: [
.project(target: "CoreDI", path: .relativeToRoot("Core/DI")),
],
includesDomainTests: true,
includesDataTests: true,
includesPresentationTests: true
)| 항목 | 값 |
|---|---|
| Tuist 버전 |
UMCApp/mise.toml 고정 (4.155.0) |
| Deployment Target | iOS 26.4 / watchOS 26.4 |
| Product Type | 모든 모듈 .staticFramework
|
| Bundle ID | 앱 com.umc.product · Core dev.umc.core.* · Feature dev.umc.feature.*.*
|
| 앱 버전 |
MARKETING_VERSION = 3.0.0, CURRENT_PROJECT_VERSION는 TUIST_BUILD_NUMBER 환경변수 (기본 1) |
| 서명 |
DEVELOPMENT_TEAM / CODE_SIGN_STYLE을 매니페스트에 고정 (generate 시 날아가므로) |
| 인터페이스 스타일 |
UIUserInterfaceStyle = Light 고정 (검증된 다크 시안이 없음) |
| 외부 의존성 | Moya 15.0.3 · Kingfisher 8.6.1 · kakao-ios-sdk 2.27.0 · GoogleSignIn-iOS 9.1.0 · firebase-ios-sdk 12.7.0 |
Tuist 버전을 올릴 때는
mise.toml만 수정하고 PR 본문에 릴리스 노트를 첨부합니다. Makefile / 로컬 tuist 설치는 손대지 않습니다.
| 키 | 이유 |
|---|---|
NSLocalNetworkUsageDescription + NSBonjourServices
|
MPC 근거리 명함 교환. 없으면 MPC가 시작조차 안 됨. 서비스 타입은 MPCTransport.serviceType과 동일해야 함 |
NSNearbyInteractionUsageDescription |
명함 교환 거리 측정 |
NSCameraUsageDescription |
명함 QR 스캔 |
NSPhotoLibraryAddUsageDescription |
명함 QR 이미지 저장 (읽기 없는 Add 전용 키) |
NSLocationWhenInUseUsageDescription |
GPS 스마트 출석 |
CFBundleURLTypes |
kakao{KEY} · Google reversed client ID · umc:// 딥링크 |
UIBackgroundModes: remote-notification |
백그라운드 푸시 → 알림 보관함 저장 |
AppProduct/AppProduct/
├── Core/ # Alert, Common(DesignSystem/Enum/Error/UIComponents), DIContainer, Manager, Navigation, NetworkAdapter, Secret
├── Utilities/ # Extensions, Keychain, Modifier, RemoteImage, Shadow, ToolBar
└── Features/ # Activity, Auth, Community, Home, MyPage, Notice, Splash, Tab
AppProduct는
v2.2.0에 동결되어 있습니다. 수정하지 않습니다.
관련 문서: Build & Run · Architecture