[아키텍처] Modular(1)
프로젝트 구성
Package Manager
CocoaPods, Carthage, SPM 등 종속성 관리를 위한 툴들로
각 기능들을 모듈로 분리 시 관리가 필요해 사용할 예정이다.
여기서는 모듈들을 Swift Package로 구성하고,
이를 SPM을 활용해 로컬에서 불러와 사용하는 형태로 구성하고자 한다.
Swift Package에 대한 자세한 사항은 여기를 확인해주세요.
구조
대략적으로 다음과 같이 구성될 예정이다.
APP - 프로젝트
Search, SearchDetail - 각 기능 모듈
Core, Network, Entity - 그 외 공통 모듈
구현
프로젝트 및 모듈 생성
프로젝트를 생성하고 SPM을 통해 local 모듈들을 추가하면 다음과 같은 구조가 된다.
모듈들은 Packages라고 하는 그룹 아래에 속하고, 프로젝트에서 직접 수정이 가능하다.
또한 SPM에서 각 모듈의 의존성을 확인하고 관리하게 된다.
APP
AppDelegate와 같은 앱 기본 구현사항과 각 모듈의 Navigator 구현을 기본 프로젝트에서 담당하게 된다.
Navigator는 각 모듈에서 정의된 Step에 따라 다른 모듈로 이동하게 된다.
// GithubSearchNavigator.swift
class GithubSearchNavigator: NavigatorProtocol {
var navigationViewController: UINavigationController?
func navigateTo(navigation: Step) {
let navigation: GithubSearchStep = navigation as! GithubSearchStep
switch navigation {
case .Detail(let repository):
let navigator = GithubSearchDetailNavigator()
let rootViewController = navigationViewController
navigator.navigationViewController = rootViewController
let viewController = GithubSearchDetailInitializer().start(with: navigator, repository: repository)
rootViewController?.pushViewController(viewController, animated: true)
break
}
}
}
Core
코어에서 구현해야 할 것은 각 Scene마다 가져야할 기본적인 형태에 대한 정의이다.
모듈로 구분시에 각 기능 모듈은 서로 존재를 모르기 때문에 Navigation에 대한 주입이 필요하고,
이를 위한 Navigator Protocol을 정의한다.
// NavigatorProtocol.swift
public protocol Step {}
public protocol NavigatorProtocol {
var navigationViewController: UINavigationController? { get set }
func navigateTo(navigation: Step)
}
// BaseViewModel.swift
public protocol BaseViewModelProtocol {
var navigator: NavigatorProtocol? { get }
}
Network
네트워크 통신에 필요한 기초를 담당하는 모듈로 여기선 Moya를 활용해 provider를 미리 생성해두었다.
// Network.swift
import Moya
public class Network {
public static let sharedInstance = Network()
private init() {}
public var provider = MoyaProvider<MultiTarget>()
}
Entity
모듈 간 공통적으로 사용하는 Entity에 대한 모듈이다.
기능 모듈
기본 MVVM 구조에 네트워크를 위한 API와 Modular 구조에 필요한 Navigation, Initailzer를 추가했다.
또한 Swift Package에서 인식을 하기 위해 Resources 폴더에 리소스들을 모아놓았다.
- Model
- View
- ViewModel
- API
- Navigation
- Resources
- Initializer
Model & ViewModel & View
모듈에서 필요한 MVVM 구조를 작성한다.
API
Moya를 기반으로 해당 기능에서 사용하는 API들을 정의한다.
// GithubSearchAPI.swift
enum GithubSearchAPI {
case fetchRepositories(text: String)
}
extension GithubSearchAPI: TargetType {
...
}
Navigation
모듈에서 필요한 Step을 정의한다.
// GithubSearchStep.swift
public enum GithubSearchStep: Step {
case Detail(repository: Repository)
}
Initializer
외부에서 모듈을 사용하기 위한 시작점이다.
해당 모듈에 필요한 정보를 이곳에서 받아 처리한다.
// GithubSearchInitializer.swift
public struct GithubSearchInitializer {
public init() {}
public func start(with navigator: NavigatorProtocol) -> UIViewController {
let viewController = UIStoryboard(name: "GithubSearch", bundle: Bundle.module).instantiateViewController(withIdentifier: "SearchViewController") as! SearchViewController
let viewModel = SearchViewModel()
viewModel.navigator = navigator
viewController.viewModel = viewModel
return viewController
}
}
결과
전체 코드는 깃허브에 있습니다.
Author And Source
이 문제에 관하여([아키텍처] Modular(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hanchi0/아키텍처-Modular1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)