Bibi's DevLog ๐ค๐
[iOS] Advanced coordinators in iOS ํด์ ๋ฐ ์ ๋ฆฌ ๋ณธ๋ฌธ
iOS ์ฑ์์ ์ฝ๋๋ค์ดํฐ ํจํด์ ์ ์ฉํ ๋ ๋ง์ฃผ์น๋ 6๊ฐ์ง ๋ฌธ์ ๋ค์ ๋ํ ํด๋ต์ ์ฐพ๋๋ค.
1. child coordinators๋ฅผ ์ธ์ , ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋๊ฐ?
์ฑ์ด ์ปค์ง๋ฉด ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ์ ์์ ์ฝ๋๋ค์ดํฐ๋ฅผ ๋ ํ์๊ฐ ์๋ค.
- ์์ ์ฝ๋๋ค์ดํฐ๋ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ธฐ๋ฅ(์ฑ ์)์ ๋งก๋๋ค
- ์์ ์ฝ๋๋ค์ดํฐ ํ๋์ ํ๋ฆ์ด ๋๋ฌ์ ๋, ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ์๊ฒ ์ด๋ฅผ ์๋ฆฌ๊ณ , ๋ค๋ฅธ ๊ณณ์ผ๋ก ํ๋ฆ์ ์ด์ด์ค๋ค.
- ๋ณต์กํ ์ฑ์ ๊ธฐ๋ฅ์ ์๊ฒ ๋๋์ด ์ฌ์ฌ์ฉ์ด ์ฝ๊ฒ ํจ
child coordinator ์์
class BuyCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
// we'll add code here
let vc = BuyViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: true)
}
}
์์ ์ฝ๋๋ค์ดํฐ๊ฐ ์์๋๋ฐ ์๋ก ์์ฑํ ๊ฒ์ด๋ฏ๋ก, start()๋ฉ์๋ ๋ด์ฉ์ MainCoordinator์ ํด๋น ๋ทฐ์ปจ ์์ฑ ๋ฉ์๋๋ก๋ถํฐ ๊ฐ์ ธ์์ ์ฑ์ด๋ค.
๊ทธ๋ค์ MainCoordinator์์ ๋ทฐ์ปจ์ ์ง์ ๋ง๋ค๋ ๋ถ๋ถ์
BuyCoordinator
๋ฅผ ๋ง๋๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊พผ๋ค.let child = BuyCoordinator(navigationController: navigationController) childCoordinators.append(child) child.start() child.parentCoordinator = self
๋ํ ๋ทฐ์ปจ์ coordinator์ ํ์ ์
MainCoordinator
์์BuyCoordinator
๋ก ๋ฐ๊พผ๋ค.์ด์
MainCoordinator
์BuyCoordinator
๋ฅผ ์ฐ๊ฒฐํด ์ค ๊ฒ์ด๋ค - ํต์ ์ด ๋๋๋กBuyCoordinator
์ parentCoordinator๋กMainCoordinator
๋ฅผ ์ฐ๊ฒฐํด ์ค๋คweak var parentCoordinator: MainCoordinator?
- MainCoordinator๊ฐ ์ด๋ฏธ ์์ ์ฝ๋๋ค์ดํฐ๋ฅผ ๊ฐ์ง๋ฏ๋ก weak๋ก ์ ์ธchild.parentCoordinator = self
๋ฅผ ์ถ๊ฐํด ์ค๋ค.
๊ทธ๋ค์, BuyViewController์ ์์ ์ด ๋๋๋ฉด ๋ทฐ์ปจ์์ ์ฝ๋๋ค์ดํฐ๋ก ์ด๋ฅผ ์๋ฆฌ๋๋ก ํด์ผ ํ๋ค.
์ฌ๋ฌ ๋ฐฉ๋ฒ(2.์์ ๊ฐ์ ํ ๊ฒ์) ์ด ์์ง๋ง ์ฌ๊ธฐ์๋
viewDidDisappear()
๋ฅผ ์ฌ์ฉํ๋ค.override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) coordinator?.didFinishBuying() }
์์์ ํธ์ถํ๋ didFinishBuying() ์ BuyCoordinator์ ๊ตฌํํ๋ค.
์ฒ๋ฆฌ ๋ฐฉ์์ ์ฑ ํ๋ฆ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๊ฒ ์ง๋ง ์ฌ๊ธฐ์๋ ํน๋ณํ ๋์์ด ํ์ํ์ง ์์ ๊ฒฝ์ฐ๋ก ๊ฐ์ ํ๊ณ ๊ตฌํํ๋ค.
func didFinishBuying() { parentCoordinator?.childDidFinish(self) }
์์์ ํธ์ถํ๋ childDidFinish()๋ฅผ MainCoordinator์ ๊ตฌํํ๋ค.
===
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ค - ๋ฐฐ์ด ๋ด์ ์์ ์ฝ๋๋ค์ดํฐ๊ฐ ์๋์ง ํ์ธํ๊ธฐ ์ํด. ํด๋์ค์๋ง ์ฌ์ฉ ๊ฐ๋ฅfunc childDidFinish(_ child: Coordinator?) { for (index, coordinator) in childCoordinators.enumerated() { if coordinator === child { childCoordinators.remove(at: index) break } } }
ํด๋์ค์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํจ์ ๋ณด์ฅํ๊ธฐ ์ํด
Coordinator
ํ๋กํ ์ฝ์ดAnyObject
๋ฅผ ์ค์ํ๋๋ก ํ๋ฉด ์ข๋ค.protocol Coordinator: AnyObject { ... }
2. navigation controller๋ก๋ถํฐ ๋ค๋ก ์ด๋ํ๋ ๊ฒ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋๊ฐ?
๋ฉ์ธ ์ฝ๋๋ค์ดํฐ๊ฐ ๋ด๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ์์ ์ํธ์์ฉ์ ์ง์ ์ ์ผ๋ก ๊ฐ์งํ๋๋ก ๋ง๋ ๋ค.
- ๊ธฐ์กด ์ฝ๋์์ ๋ทฐ์ปจ์
viewDidDisappear()
์ ์ฝ๋๋ค์ดํฐ์didFinishBuying()
์ ์ฃผ์ ์ฒ๋ฆฌํ๋ค. - ๋ ๊ฐ์ ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊ฟ ๊ฒ์ด๊ธฐ ๋๋ฌธ
- ๊ธฐ์กด ์ฝ๋์์ ๋ทฐ์ปจ์
๋ฉ์ธ ์ฝ๋๋ค์ดํฐ๊ฐ
NSObject
๋ฅผ ์์ํ๋๋ก ํ ๋ค์,UINavigationControllerDelegate
ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก ํ๋ค. (NSObject๋ฅผ ์์ํด์ผ๋ง UINavigationControllerDelegate ํ๋กํ ์ฝ์ ์ฑํํ ์ ์๊ธฐ ๋๋ฌธ)class MainCoordinator: NSObject, Coordinator, UINavigationControllerDelegate
๊ทธ๋ค์, ๋ฉ์ธ ์ฝ๋๋ค์ดํฐ๋ฅผ ๋ด๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ์ delegate๋ก ์ง์ ํ์ฌ
- ๋ทฐ์ปจํธ๋กค๋ฌ๊ฐ ๋ณด์ฌ์ง ๋๋ง๋ค ๋ด๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ๊ฐ ๋ฉ์ธ ์ฝ๋๋ค์ดํฐ์๊ฒ ์๋ ค ์ฃผ๋๋ก ํ๋ ์์ .
- start()์
navigationController.delegate = self
๋ฅผ ์ถ๊ฐํ๋ค
๋ค๋ก ์ด๋ํ๊ธฐ ์ํ ๋์์ ๊ตฌํํ ์ ์๋ค. -
UINavigationControllerDelegate
์didShow()
๋ฅผ ๊ตฌํํ๋คMainCoordinator
์ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ค:์ด์ ์ ์ด๋ค ๋ทฐ์ปจ์ผ๋ก๋ถํฐ ์ด๋ํ๋์ง ์ฝ์ด๋ธ๋ค
์ด์ ๋ทฐ์ปจ์ด ์์ง navigationStack์ ์กด์ฌํ๋ค๋ฉด : pop์ด ์๋ push๋์์ผ๋ก ์ธ์๋ ๊ฒ์
- ์๋ฌด ์กฐ์น๋ ํ ํ์ ์๋ค (return)
์ด์ ๋ทฐ์ปจ์ด navigationStack์ ์กด์ฌํ์ง ์๋๋ค๋ฉด : pop๋ ๊ฒ์ด ๋ง์
- pop๋ ๋ทฐ์ปจ์ coordinator๋ฅผ ์ฝ์ด์์ childCoordinators์์ ์ญ์ ํด ์ค์ผ ํจ
// MainCoordinator func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { // ์ด๋ค ๋ทฐ์ปจ์ผ๋ก๋ถํฐ ์ด๋ํ๋ ๊ฒ์ธ์ง ์กฐํ Read the view controller weโre moving from. guard let fromViewController = navigationController.transitionCoordinator?.viewController(forKey: .from) else { return } // Check whether our view controller array already contains that view controller. // ์ฐ๋ฆฌ์ VC ๋ฐฐ์ด์ ํด๋น ๋ทฐ์ปจ์ด ์กด์ฌํ๋์ง ํ์ธ // If it does it means weโre pushing a different view controller on top rather than popping it, so exit. // ๋ง์ฝ ์กด์ฌํ๋ค๋ฉด ๊ทธ๊ฒ์ pop์ด ์๋ ์ต์์์ ๋ค๋ฅธ ๋ทฐ์ปจ์ pushํ๋ ค๋ ๊ฒ์์ ์๋ฏธํ๋ฏ๋ก, ์ข ๋ฃํจ if navigationController.viewControllers.contains(fromViewController) { return } // ๋ทฐ์ปจ์ popํ๋ค๋ ์๋ฏธ์ด๋ฏ๋ก, ๊ทธ๊ฒ์ด BuyViewController์ธ์ง ํ์ธ // Weโre still here โ it means weโre popping the view controller, so we can check whether itโs a buy view controller if let buyViewController = fromViewController as? BuyViewController { // BuyViewController๊ฐ ๋ง๋ค๋ฉด ๊ทธ๊ฒ์ ์ง์ด๋ค // We're popping a buy view controller; end its coordinator childDidFinish(buyViewController.coordinator) } }
๋ค๋ก ๊ฐ๋ ์์ ์ด ๊น๋ค๋ก์ด ์ด์ ๋ Coordinator์ ์ํด ๋ฐ๋๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋คํํ UINavigationControllerDelegate ํ๋กํ ์ฝ๋ก ์ด๋ฌํ ์ด๋ฒคํธ๋ฅผ ๊น๋ํ๊ฒ ๋ชจ๋ํฐ๋ง ํ ์ ์๋ค.
3. view controller๋ค ์ฌ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ์ ๋ฌํ๋๊ฐ?
๋ทฐ ์ปจํธ๋กค๋ฌ ์ฌ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ ์ฝ๋๋ค์ดํฐ๊ฐ ์์ ๋ ๋ ์ด๋ ค์ ๋ณด์ด์ง๋ง, ์ค์ ๋ก๋ ์ฝ๋๋ค์ดํฐ ์ฌ์ฉ์ ๋ทฐ ์ปจํธ๋กค๋ฌ ์ฌ์ด์ hard link๋ฅผ ์์ฑํ์ง ์๋ ๊ฒ์ด ๋ณด์ฅ๋๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
๋ ธํธ : ์ดํ ๊ณผ์ ์ ๋ฐ๋ผํ๊ธฐ ์ํด์๋ ์๋์ Coordinators ํ๋ก์ ํธ๋ก ๋๋๋ฆฌ์ญ์์ค.
๋ทฐ์ปจํธ๋กค๋ฌ์ ์ ์ฅํ ๋ฐ์ดํฐ ์ ์ธ
// BuyViewController์ ์ถ๊ฐ
var selectedProduct = 0
์ด ๋ฐ์ดํฐ๊ฐ ๋ทฐ์ปจ์ด ์์ฑ๋ ๋ ์ ๊ณต๋์ด์ผ ํ๋ค๋ฉด, ์ด ๋ทฐ์ปจ์ ์์ฑํ๋ ์ฝ๋๋ค์ดํฐ์์ ๋งค๊ฐ๋ณ์๋ก ๋๊ฒจ์ฃผ์ด์ผ ํ๋ค.
MainCoordinator์ ๋ทฐ์ปจ ์์ฑ ๋ฉ์๋ ์์
func buySubscription(to productType: Int) {
let vc = BuyViewController.instantiate()
vc.selectedProduct = productType // ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์์ ์ง์
vc.coordinator = self
navigationController.pushViewController(vc, animated: true)
}
๋ทฐ์ปจ์์ ์ฝ๋๋ค์ดํฐ๋ก ์์ ์ ๋๊ธธ ๋ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ
// BuyViewController์ ๋ฉ์๋
@IBAction func buyTapped(_ sender: Any) {
coordinator?.buySubscription(to: product.selectedSegmentIndex)
}
์ค์ํ ์ ์,
๋ทฐ ์ปจํธ๋กค๋ฌ๋ ๋ค๋ฅธ ๋ทฐ ์ปจํธ๋กค๋ฌ๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ์ ๋ชฐ๋ผ์ผ ํ๋ค.
๋ทฐ์ปจ์ ์ฝ๋๋ค์ดํฐ์๊ฒ โ์ด๋๋ก๋ ๊ฐ ์ ์๋' ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค - ๊ทธ ๋ฐ์ดํฐ๋ ๋คํธ์ํฌ ์์ฒญ์ ๋ณด๋ด๊ฑฐ๋, ๋ค๋ฅธ ๋ทฐ์ปจ์ ๋ณด์ฌ์ฃผ๊ฑฐ๋, ๋๋ ๋ค๋ฅธ ์ด๋ค ์์ ์ ์ํ ๊ฒ์ด๋ค.
์ฝ๋๋ค์ดํฐ๋ ๋ชฉ์ ์ง๋ฅผ ํ์ ํ๊ฒ ํด ์ค๋ค - ๋ฐ๊ณ ์๋ ๊ฐ(๋งค๊ฐ๋ณ์)์ด ๋ฌด์์ ์๋ฏธํ๋์ง๋ฅผ ๊ฒฐ์ ํ๋ค.
4. coordinator์ tab bar controller๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ๋๊ฐ?
์ฑ์ ๊ธฐ๋ฅ์ ๋ช ํํ๊ฒ ๋๋์ด ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ผ๋ก tab bar controller๋ฅผ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉํ๋ค. ์ฝ๋๋ค์ดํฐ๋ tab bar controller์๋ ์ ๋์ํ๋ค - ์ฝ๋๋ค์ดํฐ๋ ๊ทธ๊ฒ๋ค์ ํจ๊ป ์ ๋ฌถ์ด๋๋ค(cinch).
์ฑ ๋ด๋ถ์ ๊ฐ ํญ๋ค์ด ๊ฐ ์ฝ๋๋ค์ดํฐ์ ์ํด ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๊ฐ ํญ๋ง๋ค ํ๋์ฉ์ ์ฝ๋๋ค์ดํฐ๋ฅผ ๊ฐ์ง๋ค.
์๋๋ tab bar controller๋ฅผ ๊ด๋ฆฌํ๋ ๋ช๊ฐ์ง ๋ฐฉ๋ฒ์ด๋ค.
MainTabBarController๋ฅผ ๋ง๋ ๋ค
UITabBarController๋ฅผ ์์ํ๋ MainTabBarController๋ฅผ ๋ง๋ ๋ค.
์ด ์ปจํธ๋กค๋ฌ๋ ๊ฐ ํญ์ ๋ํ ์ฝ๋๋ค์ดํฐ๋ฅผ ํ๋กํผํฐ๋ก ๊ฐ๋๋ค.
- ํ๋์ ์ฝ๋๋ค์ดํฐ๋ฅผ ํ๋กํผํฐ๋ก ๋ฃ์ด๋ณด์.
- viewDidLoad()์์ ๊ฐ ์ฝ๋๋ค์ดํฐ์ start()๋ฅผ ํธ์ถํ๋ค
- ๊ฐ ์ฝ๋๋ค์ดํฐ๊ฐ ๊ธฐ๋ณธ ๋ทฐ์ปจํธ๋กค๋ฌ๋ฅผ ์ค๋นํ๋๋ก ํ๋ค
- viewControllers ํ๋กํผํฐ๋ฅผ ํญ๋ฐ์ปจํธ๋กค๋ฌ ๋ฐฐ์ด๋ก ์ง์ ํ๋ค.
- ์ฝ๋๋ค์ดํฐ์์ ์ฌ์ฉํ๋ ๊ฐ ๋ด๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ๋ฅผ ์ด์ฉํ๋ค
// MainTabBarController์ ์ถ๊ฐ
let mainCoordinator = MainCoordinator(navigationController: UINavigationController())
override func viewDidLoad() {
main.start()
viewControllers = [main.navigationController]
}
๊ฐ ๋ทฐ์ปจํธ๋กค๋ฌ์ tab bar item ์ถ๊ฐ
์ถ๊ฐํ์ง ์์ผ๋ฉด ํญ๋ฐ์์ ๋ณผ ์๊ฐ ์๋ค.
coordinator์์ start()ํ ๋ ์ค์ ํด์ค ์ ์๋ค.
// MainCoordinator
vc.tabBarItem = UITabBarItem(tabBarSystemItem: .favorites, tag: 0)
AppDelegate์์ rootViewController๋ก MainTabBarController๋ฅผ ์ง์ ํ๋ค
//AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = MainTabBarController()
window?.makeKeyAndVisible()
return true
}
ํญ๋ฐ์ปจํธ๋กค๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋๋ํ ๋ฐฉ๋ฒ์ ํญ ํ๋๋ง๋ค ํ๋์ ์ฝ๋๋ค์ดํฐ๋ฅผ ๋๋ ๊ฒ์ด๋ค.
์ด๋ ์ฑ์ ๋ค๋ฅธ ๋ถ๋ถ๋ค์ด ์ ์ ํ ๋ถ๋ฆฌ๋๋๋ก ํด์ค๋ค.
5. segue๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋๊ฐ?
segue๋ ๋ทฐ ์ปจํธ๋กค๋ฌ ์ฌ์ด์ ์ฐ๊ฒฐ์ ์์ฑํจ์ผ๋ก์ ์คํ ๋ฆฌ๋ณด๋์ ์ถ๊ฐ๋๋ค.
segue๋ iOS์ ์ํด ์๋์ผ๋ก, ๋๋ prepare(for segue:)
๋ฉ์๋๋ฅผ ํธ์ถํจ์ผ๋ก์ ๋ฐ๋๋๋ค.
๋ฌธ์ ๋ segue๊ฐ ์ฝ๋๋ค์ดํฐ์ ์ฃผ์ ์ฅ์ ์ค ํ๋๋ฅผ ํ๋๊ฒ ํ๋ค๋ ๊ฒ์ด๋ค: segue๋ ๊ฐ์ ๋ก ์ง์ ๋ ์ฑ์ ํ๋ฆ์ ๋ง๋ ๋ค. ์ด๋ ๋ทฐ์ปจํธ๋กค๋ฌ๋ฅผ ์์ ๋กญ๊ฒ ์ฌ๋ฐฐ์นํ๋ ๊ฒ์ ๋ง๋๋ค.
๊ฒฐ๋ก : ๊ฐ๋ฅํ๋ฉด segue์ฌ์ฉ์ ์ง์ํ๋ค(์ ์ด๋ ๊ธ์ด์ด๋ ์ฐ์ง ์๋๋ค๊ณ ํจ).
6. ์ด๋ป๊ฒ ํ๋กํ ์ฝ์ด๋ ํด๋ก์ ๋ฅผ (์ฝ๋๋ค์ดํฐ) ๋์ ์ฌ์ฉํ๋๊ฐ?
(์ฝ๋๋ค์ดํฐ ํ์ ๋์ ํ๋กํ ์ฝ์ด๋ ํด๋ก์ ์ฌ์ฉํ๊ธฐ)
์ฝ๋๋ค์ดํฐ๋ฅผ ์ฌ์ฉํ ๋ ํผ๋์ค๋ฌ์ธ ์ ์๋ ๋ถ๋ถ์ ์ฝ๋๋ค์ดํฐ์ delegate์ ์ฐจ์ด์ ์ด๋ค. ์ฌ์ค์ ์ฝ๋๋ค์ดํฐ์ delegate๋ ๋ค๋ฅด์ง ์๋ค - ์ฝ๋๋ค์ดํฐ๋ ๊ทธ์ ํจ๊ณผ์ ์ผ๋ก ์ ๋ฌธํ๋ delegate์ด๋ค. ์ฌ์ค, ๋ทฐ์ปจํธ๋กค๋ฌ๋ฅผ ๊ด๋ฆฌํ๋ coordinator ํ๋์ ์ด๋ฆ์ delegate๋ก ๋ฐ๊พธ๋ฉด ๊ทธ๋๋ก ์๋ํ๋ค.
coordinator๋ผ๋ ์ด๋ฆ์ ์ฐ๋ ๊ฒ์ ์ฅ์ ์, ๊ทธ๊ฒ์ด ์ฑ ์ ๋ฐ์ ๋ด๋น๊ฒ์ด์ ์ ์ฒ๋ฆฌํ๋ ์ ๋ฌธํ๋ delegate์์ ์๋ฏธํจ์ด ๋ช ํํ๋ค๋ ๊ฒ์ด๋ค. ๋น์ ์ ํ๋์ ๋ทฐ์ปจํธ๋กค๋ฌ์ ๋ช๋ช์ ์๋ก ๋ค๋ฅธ delegate๋ฅผ ๊ฐ์ง ์ ์๊ณ , ์ฑ ๋ด๋ถ์์ ํจ๊ป ์๋ํ๊ฒ ์ง๋ง, ๋น์ ์ด ๊ทธ ์ด๋ฆ์ ๊ทธ์ delegate๋ก ์ง๋๋ค๋ฉด ํผ๋์ด ์ฌ ์ ์๋ค. ์ด๊ฒ์ coordinator๋ผ๊ณ ์ด๋ฆ์ง์์ผ๋ก์จ ์ฐ๋ฆฌ๋ ์ญํ ์ ๋ช ํํ๊ฒ ๋ง๋ค ์ ์๋ค: ์ด๊ฒ์ด ์ฑ์ ๋ฐ์ ์ํค๋ ์์์ด๋ค.
์ฝ๋๋ค์ดํฐ์ ์ด๋ฆ์ delegate๋ก ๋ณ๊ฒฝํ๋ ๋์ ๋๊ฐ์ง ๋์์ด ์๋ค.
- ํ๋กํ ์ฝ ์ฌ์ฉํ๊ธฐ
- ํด๋ก์ ์ฌ์ฉํ๊ธฐ
ํ๋กํ ์ฝ ์ฌ์ฉํ๊ธฐ
- ํฐ ์ฑ์ผ ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
- ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ ์์ ๋กญ๊ฒ ๋ค๋ฅด๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ
๋จผ์ ๋ฉ์ธ ์ฝ๋๋ค์ดํฐ ๋ด์ VC ์์ฑ ๋ฉ์๋๋ฅผ ๋ณด๊ณ ๊ณตํต ํ๋กํ ์ฝ์ ๋ง๋ ๋ค.
์ฌ๊ธฐ์๋ buySubscription()
๊ณผ createAccount()
๊ฐ ์กด์ฌํ๋ฏ๋ก, ์ด๊ฒ๋ค์ ์ ํ๋กํ ์ฝ๋ก ๋ฌถ์ ์ ์๋ค.
// Buying
protocol Buying: AnyObject {
func buySubscription()
}
// AccountCreating
protocol AccountCreating: AnyObject {
func createAccount()
}
์ฝ๋๋ค์ดํฐ๊ฐ ์์ ํ๋กํ ์ฝ์ ์ฑํํ๋๋ก ํ๋ค
// MainCoordinator
class MainCoordinator: Coordinator, Buying, AccountCreating
ViewController๊ฐ ๊ตฌ์ฒด ํ์ ๋์ ํ๋กํ ์ฝ์ ์ฐธ์กฐํ๋๋ก ํ๋ค
// ViewController
weak var coordinator: (Buying & AccountCreating)?
์ด์ ๋ ํ๋กํ ์ฝ์ด ๊ตฌํ๋๋ ํ, ์ด๋ป๊ฒ ๊ตฌํํ๋์ง๋ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค - ๊ทธ๊ฒ์ ์ฝ๋๋ค์ดํฐ์ผ์๋ ์๊ณ , ์๋ ์๋ ์๋ค.
ํ๋กํ ์ฝ์ ์ฌ์ฉํ๋ฉดโฆ
ํ๋กํ ์ฝ์ ์ฌ์ฉํ๋ ๊ฒ์ ํฐ ์ฑ์ ์์ ํ๋ฉด์ ๋ ๋ง์ ์ ์ฐ์ฑ์ ํ์๋ก ํ ๋ ๋งค์ฐ ์ ์ฉํ๋ค.
- ์ํ ๋ ์์ ๋กญ๊ฒ ์๋ก์ด ํ๋กํ ์ฝ์ ์ถ๊ฐํ ์ ์๋ค
- A/B ํ ์คํธ๋ฅผ ์ํด ๋ค๋ฅธ ์ฝ๋๋ค์ดํฐ๋ก ์ ํํ๊ธฐ ์ฝ๋ค
- ํจ์ฌ ๋ ์ ์ฐํ๋ค - ํ๋กํ ์ฝ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ํน์ ํ์ ์ด ์๋ ์ํ๋ ๋์์ ๊ธฐ์ ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ
ํด๋ก์ ์ฌ์ฉํ๊ธฐ
์ฝ๋๋ค์ดํฐ ๊ตฌ์ฒดํ์ ๊ณผ ํ๋กํ ์ฝ์ ๋ชจ๋ ์ฌ์ฉํ์ง ์๊ณ , ๋์ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
๋ทฐ์ปจํธ๋กค๋ฌ์ ์ํด ๋ฐ๋๋๋ ์ก์ ์ด 1~2๊ฐ๋ฟ์ผ ๋ ์ ์ฉํ๋ค.
ViewController์ ๋ฉ์๋๋ฅผ ํ๋กํผํฐ๋ก ์ ์ํ๋ค
// ViewController
var buyAction: (() -> Void)?
var createAccountAction: (() -> Void)?
์ฌ์ฉํ ๋๋ ์๋์ ๊ฐ์ด ํธ์ถํ๋ค
// ViewController
@IBAction func buyTapped(_ sender: Any) {
buyAction?()
}
@IBAction func createAccountTapped(_ sender: Any) {
createAccountAction?()
}
์ฝ๋๋ค์ดํฐ์์ ํด๋น ํด๋ก์ ๋ค์ ์ ์ํด ์ค๋ค
์ฝ๋๋ค์ดํฐ๊ฐ ๋ทฐ์ปจ์ ์์ฑํ ๋ ํด๋น ํด๋ก์ ๋ค์ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ง ์ ์ํด ์ค๋ค.
- ๊ธฐ์กด coordinator ํ๋กํผํฐ๋ฅผ ์ญ์ ํ๊ณ
- buyAction๊ณผ createAccountAction ํ๋กํผํฐ๋ฅผ ์ค์ ํ๋ค
// MainCoordinator
vc.buyAction = { [weak self] in
self?.buySubscription()
}
vc.createAccountAction = { [weak self] in
self?.createAccount()
}
์ด๋ ๊ฒ ๋ง๋ค๋ฉด ๋ทฐ์ปจํธ๋กค๋ฌ๋ ์ฝ๋๋ค์ดํฐ๊ฐ ๋ด๋น๊ฒ์ด์ ์ ์ ์ดํ๋ค๋ ๊ฒ๋ ๋ชจ๋ฅด๊ฒ ํ ์ ์๋ค.
ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ฉด..
- ์ฝ๋๋ค์ดํฐ์๊ฒ ๋จ์ง 1๊ฐ ๋๋ 2๊ฐ์ ์ฝ๋ฐฑ๋ง์ ๋ณด๋ผ ๋ ์ข๋ค
- ๋ทฐ์ปจํธ๋กค๋ฌ๋ฅผ ์์ ํ ๋ ๋ฆฝ์ ์ผ๋ก ๋ง๋ค ์ ์๋ค - ์ฝ๋๋ค์ดํฐ์ ์กด์ฌ์กฐ์ฐจ ๋ชจ๋ฅด๊ฒ
- ํ์ง๋ง ๊ท๋ชจ๋ฅผ ํค์ฐ๊ธฐ์๋ ์ข์ง ์๋ค - 3๊ฐ ์ด์์ ํด๋ก์ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ๋ค ๋ณด๋ฉด ํ๋กํ ์ฝ๋ก ๋ฐ๊พธ๊ณ ์ถ์ด์ง ๊ฒ.
https://khanlou.com/tag/advanced-coordinators/
์ฝ๋๋ค์ดํฐ ํจํด์ ๋ง๋ Khanlou์ ๋ธ๋ก๊ทธ ๊ธ์ ์ฝ์ด๋ณด๊ธฐ๋ฅผ ์ถ์ฒ.
'๐ฑ๐ iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] Coordinator (2) - ์ฝ๋๋ค์ดํฐ ํจํด, ์์ ์ ํจ๊ป ๊ตฌํํ๊ธฐ (0) | 2022.11.25 |
---|---|
[iOS] Coordinator (1) - ์ฝ๋๋ค์ดํฐ๋ ๋ฌด์์ธ๊ฐ? ๊ฐ๋ ์ดํดํ๊ธฐ (0) | 2022.11.25 |
[iOS] How to use the coordinator pattern in iOS apps ํด์ ๋ฐ ์ ๋ฆฌ (0) | 2022.11.25 |
Environment : ๊ฐ์ฒด์ ์์กด์ฑ ํ๊ฒฝ ๋ง๋ค๊ธฐ (0) | 2022.10.21 |
[๊ณฐํ๊น๋] RxSwift + MVVM ์ ๋ฆฌ (0) | 2022.06.06 |