Skip to content

코딩 컨벤션

파일 구조 컨벤션

Feature 모듈 디렉토리 구조

Feature 모듈은 2가지 구조 중 하나를 따릅니다. Feature의 규모와 성격에 따라 선택합니다.

화면 수가 많고 공유 ViewModel이 필요한 경우:

Features/{FeatureName}/
  Project.swift           -- Tuist 프로젝트 정의
  Sources/
    Assembly/             -- Swinject Assembly
      {FeatureName}Assembly.swift
    PresentationSources/  -- 공유 ViewModel / Manager / Model
      {Feature}ViewModel.swift
      Managers/           -- Feature 전용 Manager/Helper
      Model/              -- Presentation Model
    UISources/            -- SwiftUI View (화면별 하위 디렉토리)
      {Screen}/
        {Screen}Builder.swift
        {Screen}View.swift
        {Screen}ViewModel.swift  -- 화면 전용 ViewModel
    Protocols/            -- Feature 내부 Protocol
  Resources/              -- Feature 전용 리소스
  Tests/                  -- Unit Test

ViewModel은 PresentationSources/UISources/{Screen}/ 두 곳에 모두 존재할 수 있습니다. 여러 화면에서 공유하는 ViewModel은 PresentationSources/에, 특정 화면 전용 ViewModel은 해당 화면 디렉토리에 배치합니다.

화면 단위 파일 구성

하나의 화면은 최소 3개의 파일로 구성됩니다:

파일역할
{Screen}Builder.swiftBuilder 프로토콜 + 구현체 + Dependency 구조체 + UIHostingController 서브클래스
{Screen}View.swiftSwiftUI View
{Screen}ViewModel.swiftViewModel (PresentationSources/ 또는 해당 화면 디렉토리에 위치)

네이밍 컨벤션

파일 네이밍

유형패턴예시
SwiftUI View{Screen}View.swiftHomeView.swift, LoopMainView.swift
ViewModel{Screen}ViewModel.swiftHomeViewModel.swift
Builder{Screen}Builder.swiftHomeBuilder.swift
API Target{Domain}API.swiftAuthAPI.swift, HomeAPI.swift
Repository Protocol{Domain}Repository.swiftAuthRepository.swift
DataSource Impl{Domain}DataSourceImpl.swiftAuthDataSourceImpl.swift
Request DTO{Action}Request.swiftLoginRequest.swift
Response DTO{Action}Response.swiftLoginResponse.swift
Assembly{Module}Assembly.swiftHomeAssembly.swift
Entity{ModelName}.swiftUser.swift, Loop.swift
Extension{Type}+ext.swiftString+ext.swift, Date+ext.swift

Protocol 네이밍

유형패턴예시
Builder Protocol{Screen}BuildableHomeBuildable
Repository Protocol{Domain}RepositoryHomeRepository
UseCase Protocol{Action}UseCaseAccountUseCase
Manager Protocol{Domain}ManagerContactManager

구현체 네이밍

유형패턴예시
UseCase Impl{Action}UseCaseImplAccountUseCaseImpl
DataSource Impl{Domain}DataSourceImplAuthDataSourceImpl
Manager Impl{Domain}ManagerImplContactManagerImpl

아키텍처 컨벤션

MVVM 패턴 규칙

  • ViewModel은 ObservableObject를 채택하고 @Published 프로퍼티를 통해 상태를 노출
  • View는 @StateObject 또는 @ObservedObject로 ViewModel을 관찰
  • ViewModel에서 View로의 데이터 흐름은 단방향
  • ViewModel은 Domain 레이어에 주로 의존하지만, UIKit/SwiftUI import도 필요에 따라 허용

Dependency Injection 규칙

  • 모든 의존성은 생성자 주입 (Constructor Injection) 사용
  • Builder의 Dependency 구조체에 필요한 의존성 명시
  • Protocol 기반 의존성 주입 (구체 타입 직접 주입 금지)

레이어 의존성 규칙

허용: Feature --> Domain --> (없음)
허용: Feature --> Repository (Assembly에서만)
허용: Repository --> Domain, Networking
금지: Domain --> Repository, Networking, Feature
금지: Feature A --> Feature B (Interface 모듈 통해서만)

다국어(Localization)

언어코드파일
영어enen.lproj/Localizable.strings
한국어koko.lproj/Localizable.strings
일본어jaja.lproj/Localizable.strings

코드 스타일

Swift 일반 규칙

  • guard let / guard 구문을 early return에 활용
  • async/await 사용 (콜백 기반 코드 지양)
  • enum의 associated value를 적극 활용 (API Target 등)
  • Access control을 명시적으로 지정 (public, internal, private)
  • final class 사용 (상속이 필요 없는 경우)
  • @unchecked Sendable은 Thread Safety가 보장되는 경우에만 사용

SwiftUI 규칙

  • View body는 가능한 한 작게 유지
  • 복잡한 뷰는 서브 뷰로 분리
  • ViewModifier를 활용한 공통 스타일 적용 (DesignSystem 모듈)
  • DesignSystem 모듈의 Semantic Color / Foundation Color 사용

변경 이력

날짜내용
2026-03-10Feature 모듈 디렉토리 구조를 대형/소형 2가지 패턴으로 세분화, ViewModel 위치 규칙 수정 (PresentationSources + UISources 모두 가능), MVVM 규칙에서 UIKit/SwiftUI import 금지 조항 제거 (실제 코드 반영), Builder 파일 역할에 UIHostingController 서브클래스 추가