iOS 아키텍쳐의 종류는 다양해요
MVC, MVP, MVVM, VIPER, RIBs... 등등 많은데
MVC-C, MVVM-C 이러한 표현을 보신적도 있지않나요??
여기서 C는 Coordinator를 의미해요
Coordinator란??
화면의 흐름을 제어해주는 역할
라우팅
VC관리
이런 단어들이 어울리겟네요
말이 좀 어렵지만..
위 그림처럼 이런 원리라고 생각하면 쉽게 접근할 수 있어요
VC에 ViewModel를 의존성주입(DI)하듯
VC를 생성하고 필요한 의존성주입을 할 수 있어요
기존에는 Storyboard에서 VC를 관리하고 이동시켰어요
라우팅관리를 모두 Storyboard에서 했었죠
혹은 ViewController가 담당했죠
Coordinator를 사용하면
Coordinator가 VC의 이벤트도 담당하고
라우팅기능 처럼
화면에 대한 동작을 처리해요
Coordinator를 사용해서
그 로직을 따로 분리시키는 작업을 하는거에요
VC의 책임이 좀 줄어드는것 같죠?
이 아키텍쳐를 왜 쓰나요??
화면간 연결을 더 쉽게 관리할 수 있구요
VC를 더 쉽게 재사용할 수 있구요
계층 관리가 용이하죠
VC가 만들어질 때 의존성 주입(DI)를 통해서 사용할 수 있죠
한 번해보면서 이해해볼게요
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
var nav: UINavigationController { get set }
func start()
}
프로토콜을 만들어줘요
기능으로는 자식Coordinator를 가지고있을 배열과
navigation을 담을 변수
시작시 실행될 함수를 가지고있을거에요
class MainCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var nav: UINavigationController
init(nav: UINavigationController) {
self.nav = nav
}
func start() {
let vc = MainViewController.instantiate(storyboardName: "Main")
vc.coordinator = self
nav.pushViewController(vc, animated: false)
}
func showSecondVC() {
let vc = SecondViewController.instantiate(storyboardName: "Main")
vc.coordinator = self
nav.pushViewController(vc, animated: true)
}
}
프로토콜을 채택해서 클래스를 만들어주고
start()함수를 정의해줫어요
start를 호출하면 해당하는 VC가 Navigation에 쌓이겟네요
showSecondVC()함수는 두번째화면이 보여지도록 햇어요
따라서 MainCoordinator에서는
start, showSecondVC를 통해서
2개의 VC를 관리하고 있네요
다음으로는 이제 앱시작시 설정을 변경할거에요
코디네이터를 사용하기위해서
기존의 실행환경을 바꿀거에요
plist의 Main Storyboard를 없애주고
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var coordinator: MainCoordinator?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let nav = UINavigationController()
coordinator = MainCoordinator(nav: nav)
coordinator?.start()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = nav
window?.makeKeyAndVisible()
return true
}
}
위에서 메인 스토리보드설정을 지우고
실행하면 까맣게 나올거에요
현재 window의 초기설정이 안들어가서 그래요
방금 지웟잖아요?!
새로 window를 만들어줄거에요
AppDelegate에서
window를 새로만들어주고
rootVC로 코디네이터역할을하는 네비게이션을 넣어줄거에요
그리고
makeKeyAndVisible
이건 윈도우를 새로만든경우 화면에 보여주기위해
새로 만들었다면 꼭 호출해야하는 함수에요
protocol Storyboarded {
static func instantiate(storyboardName: String) -> Self
}
extension Storyboarded where Self: UIViewController {
static func instantiate(storyboardName: String) -> Self {
let id = String(describing: self)
let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
return storyboard.instantiateViewController(withIdentifier: id) as! Self
}
}
Storyboarded 프로토콜은
스토리보드에 접근해서 자신의 타입이름을 identifier로 가진 뷰컨트롤러를 반환해주는
간편한 함수에요
이렇게 타입과 identifier을 같게해줬어요
String(describing:)
타입을 문자열로 반환해줘요
class MainViewController: UIViewController, Storyboarded {
weak var coordinator: MainCoordinator?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func nextVC(_ sender: Any) {
coordinator?.showSecondVC()
}
}
메인VC에서
버튼을 클릭하면 코디네이터의 함수를 실행시킬거에요
저함수는 위에서 두번째화면으로 가도록 정의했잖아요?
아주 잘 실행 되는걸 볼 수 있을거에요
흐름이 다른경우, 혹은 새로운 Navigation이 필요한경우
코디네이터를 새로 만들어서 관리하는 식인것 같아요
코디네이터패턴을 이해하기위해
간단하게 구현하는 과정을 작성했어요
부족한점들이 많을거에요
많은 조언 부탁드려요 :)
기본 동작을 다뤄보는 글은 다음게시물에 있어요
2020/05/22 - [iyOmSd/Title: Swift] - [Swift] Coordinator Pattern (2/2) - 기본동작
'iyOmSd > Title: Swift' 카테고리의 다른 글
[Swift] Coordinator Pattern (2/2) - 기본동작 (0) | 2020.05.22 |
---|---|
[Swift] - Alamofire 5.1 변경된 통신 및 Json Dynamic Key (0) | 2020.05.18 |
[Swift] - JavaScriptCore(1/2) (0) | 2020.05.16 |
[Swift] - TableView Header 및 Swipe Delete Action (2) | 2020.05.12 |
[Swift] - Simple Carousel Effect CollectionView With Animation (0) | 2020.05.08 |