-
Notifications
You must be signed in to change notification settings - Fork 0
Project Architecture
Hyun Sik Yoo edited this page Nov 29, 2022
·
2 revisions
- MVI(ReactorKit)
- Code base로 UI 구현 (SnapKit)
- Coordinator Pattern 사용 (프로토콜과 익스텐션을 사용해 라이트하게 사용중)
-
services
: API 통신하는 역할을 하는 서비스들이 모여있는 디렉토리입니다. -
uilts
: 앱에서 사용하는 유틸성 함수들이 모여있는 디렉토리입니다. -
models
: 데이터 클래스입니다. dto 디렉토리와 presentation 디렉토리로 나눠져있습니다.-
dto
: 서버에서 받는 응답 데이터와 1:1 맵핑되는 모델입니다. -
presentation
: 사용자들에게 보여지는 화면에서 사용되는 모델입니다. dto 모델이 presentation으로 변경되어 사용됩니다.
-
-
managers
: Analytics등 서드파티를 연결해주거나 외부에서 관리해주거나 앱 내에서 유틸성 함수들을 하나의 클래스 단위로 묶어 관리하는 매니저들의 집합입니다. -
resources
: 폰트, 이미지, 로띠등의 리소스 파일들이 속한 디렉토리입니다. -
extensions
: 앱 내에서 사용되는 익스텐션들을 별도로 모아둔 디렉토리입니다. -
domains
: 앱에서 사용자들에게 실제로 보여지는ViewController
,Reactor
,View
들이 속한 디렉토리입니다. 화면 접근에 따라 디렉토리가 구분되어있습니다.
한 화면에 대해서 사용되는 Boilerplate code는 다음과 같습니다.
-
View.swift
: UIComponent와 Layout을 정의합니다. -
ViewController.swift
: View와 Reactor를 바인딩시켜주는 역할을 합니다. -
Reactor.swift
: 비즈니스로직에 해당하는 코드들만 존재합니다. -
Coordinator.swift
: 네비게이션(화면이동) 역할을 합니다.
- BaseView를 상속받아서 사용합니다.
final class TemplateView: BaseView {
private let templateLabel = UILabel()
// ...
override func setup() { // 뷰 추가
self.addSubviews([self.templateLabel])
// ...
}
override func bindConstraints() { // 오토레이아웃 설정
self.templateLabel.snp.makeConstraints {
// ...
}
}
func bind(model: Model) {
// 모델에 따라 변경되는 뷰가 있다면 여기서 변경시킵니다.
}
}
- 프로토콜 형태로 extension으로 확장시켜서 함수를 구현합니다.
- Coordinator프로토콜을 채택해서 정의합니다.
protocol TemplateCoordinator: AnyObject, Coordinator {
func pushDetailViewController()
}
extension TemplateCoordinator {
func pushDetailViewController() {
// 네비게이팅 코드 작성!
}
}
- 비즈니스로직을 Reactor 형식에 맞춰서 정의합니다.
final class TemplateReactor: Reactor {
enum Action {
// 액션 정의
}
enum Mutation {
// 뮤테이션 정의
}
struct State {
// state 정의
}
let initialState = State()
func mutate(action: Action) -> Observable<Mutation> {
// mutate 정의
}
func reduce(state: State, mutation: Mutation) -> State {
// reduce 정의
}
}
- BaseViewController를 상속받아 정의합니다.
- 위에서 구현한 Coordinator도 채택시켜서 정의합니다.
final class TemplateViewController: BaseViewController, TemplateCoordinator, View {
private weak var coordinator: TemplateCoordinator?
private let templateView = TemplateView()
private let templateReactor = TemplateReactor()
override func loadView() {
// 뷰 설정
self.view = self.templateView
}
override func viewDidLoad() {
// 코디네이터 할당
self.coordinator = self
}
override func bindEvent() {
// 단순 이벤트 바인딩시키는 곳입니다.
}
func bind(reactor: TemplateReactor) {
// 리액터 바인딩 시키는 곳입니다.
}
}