Bibi's DevLog ๐Ÿค“๐ŸŽ

[iOS] How to use the coordinator pattern in iOS apps ํ•ด์„ ๋ฐ ์ •๋ฆฌ ๋ณธ๋ฌธ

๐Ÿ“ฑ๐ŸŽ iOS

[iOS] How to use the coordinator pattern in iOS apps ํ•ด์„ ๋ฐ ์ •๋ฆฌ

๋น„๋น„ bibi 2022. 11. 25. 01:06

How to use the coordinator pattern in iOS apps

VC๊ฐ€ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์†Œ์œ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์กฐ๊ธˆ ๋” ๊ฐ„๋‹จํ•˜๋‹ค.

์˜์–ด ํ•ด์„๊ณผ ์ฝ”๋“œ ์˜ˆ์ œ ์œ„์ฃผ๋กœ ์ •๋ฆฌ.

iOS์•ฑ์—์„œ ์ฝ”๋””๋„ค์ดํ„ฐ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

view controller์™€ navigation controller๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ.

์—ฌ๊ธฐ์„œ๋Š” child coordinator ์‚ฌ์šฉ ์ง์ „๊นŒ์ง€ ๋ฐฐ์šด๋‹ค.

child coordinator ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ ๋ฌธ์„œ์—์„œ ๋ฐฐ์šด๋‹ค.

iOS ์•ฑ์—์„œ ์ฝ”๋””๋„ค์ดํ„ฐ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด…

  • View Controller์—์„œ ์•ฑ ํƒ์ƒ‰(app navigation) ์ž‘์—…์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์šฐ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์•ฑ์˜ ํ๋ฆ„์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ViewController๋“ค์„ ๊ด€๋ฆฌํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ๋” ์‰ฌ์›Œ์ง„๋‹ค.
  • massive view controller๋ฅผ ๋ง‰๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์•ฑ์—์„œ ๋…๋ฆฝ์ ์ผ ๋•Œ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•œ๋‹ค. ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์•ฑ์˜ ํ”Œ๋กœ์šฐ ์†์—์„œ ์ž์‹ ์˜ ์œ„์น˜๋ฅผ ์˜์‹ํ•˜์ง€ ์•Š๊ณ , ๊ทธ๋ฆฌ๊ณ  ์ฒ˜์Œ๋ถ€ํ„ฐ ์ž์‹ ์ด ํ”„๋ฆ„์˜ ์ผ๋ถ€๋ผ๋Š” ๊ฒƒ์กฐ์ฐจ ๋ชจ๋ฅผ ์ •๋„๋กœ ๋…๋ฆฝ์ ์ธ ๊ฒƒ์ด ์ข‹๋‹ค.

์ด๊ฒƒ์€ ์ฝ”๋“œ์˜ ํ…Œ์ŠคํŠธ์™€ ์ถ”๋ก ์„ ์‰ฝ๊ฒŒ ํ•ด์ค„ ๋ฟ ์•„๋‹ˆ๋ผ, ๋‹น์‹ ์˜ ์•ฑ ๋‚ด๋ถ€์—์„œ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์˜ ์žฌ์‚ฌ์šฉ์„ ๋”์šฑ ์‰ฝ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค.

๋ฌด์—‡์„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š”๊ฐ€?

iOS ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋ฐฑ๋ฒˆ๋„ ๋„˜๊ฒŒ ์ž‘์„ฑํ–ˆ์„ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์‚ดํŽด๋ณด์ž.

if let vc = storyboard?.instantiateViewController(withIdentifier: "SomeVC") {
    navigationController?.pushViewController(vc, animated: true)
}

์ด๋Ÿฐ ์ฝ”๋“œ์—์„œ, ํ•˜๋‚˜์˜ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ฐ˜๋“œ์‹œ ๋‹ค๋ฅธ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ตฌ์„ฑํ•˜๊ณ , ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค.

์ด๋Š” ๋‹น์‹ ์˜ ์•ฑ์—์„œ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์„ ํ˜•์„ฑํ•œ๋‹ค: ๋‹น์‹ ์€ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๊ณ , ์‹ฌ์ง€์–ด ๊ฐ™์€ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์—ฌ๋Ÿฌ ์žฅ์†Œ์—์„œ ๋ณด์—ฌ์ ธ์•ผ ํ•  ๋•Œ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ–ˆ์„์ง€๋„ ๋ชจ๋ฅธ๋‹ค.

 

๋‹น์‹ ์ด ์•„์ดํŒจ๋“œ ์‚ฌ์šฉ์ž, VoiceOver ์‚ฌ์šฉ์ž, A/Bํ…Œ์ŠคํŠธ์˜ ์‚ฌ์šฉ์ž ์ผ๋ถ€๋ฅผ ์œ„ํ•œ ๋‹ค๋ฅธ ๋™์ž‘์„ ์›ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๊ฒ ๋Š”๊ฐ€? ๋‹น์‹ ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์„ ํƒ์€ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์— ๋” ๋งŽ์€ ๊ตฌ์„ฑ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ ๋ฟ์ด๋ฉฐ, ๋ฌธ์ œ๋Š” ๋” ์‹ฌ๊ฐํ•ด์งˆ ๋ฟ์ด๋‹ค.

 

๋” ์‹ฌ๊ฐํ•œ ๊ฒƒ์€, ์ด ๋ชจ๋“  ๊ฒƒ์ด ‘์ž์‹ ์˜ ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ปจํŠธ๋กค๋Ÿฌ์—๊ฒŒ ๋ฌด์—‡์„ ํ•˜๋ผ๊ณ  ์ง€์‹œํ•˜๋Š” ์ž์‹’์„ ํฌํ•จํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค - ์šฐ๋ฆฌ์˜ ์ฒซ ๋ฒˆ์งธ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์ž์‹ ์˜ ๋ถ€๋ชจ์—๊ฒŒ๊นŒ์ง€ ์ ‘๊ทผํ•ด, ๋ถ€๋ชจ์—๊ฒŒ ๋‘ ๋ฒˆ์งธ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ์ง€์‹œํ•œ๋‹ค.

 

์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์ฝ”๋””๋„ค์ดํ„ฐ ํŒจํ„ด์€ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์˜ ์—ฐ๊ฒฐ์„ ๋Š์–ด์„œ ๊ฐ๊ฐ์˜ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ž์‹ ์˜ ์ „ํ›„์— ๋ฌด์—‡์ด ์žˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์˜ ํ๋ฆ„์ด ์žˆ๋Š”์ง€์กฐ์ฐจ ๋ชจ๋ฅด๊ฒŒ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

 

๊ทธ ๋Œ€์‹ , ๋‹น์‹ ์˜ ์•ฑ ํ๋ฆ„(flow)์€ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ œ์–ด๋˜๋ฉฐ, ๋ทฐ๋Š” ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์†Œํ†ตํ•˜๊ฒŒ ๋œ๋‹ค. ๋งŒ์•ฝ ๋‹น์‹ ์ด ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด, ์ฝ”๋””๋„ค์ดํ„ฐ์—๊ฒŒ ์ธ์ฆ ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค. ์ฝ”๋””๋„ค์ดํ„ฐ๊ฐ€ ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํ•˜๊ฒŒ ํ‘œ์‹œํ•ด ์ค„ ๊ฒƒ์ด๋‹ค.

 

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋‹น์‹ ์€ ๋‹น์‹ ์ด ์–ด๋–ค ์ˆœ์„œ๋กœ๋“  ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ๊ทธ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋” ์ด์ƒ ๋‹น์‹ ์˜ ์•ฑ์— ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ฒฝ๋กœ๋Š” ์—†๋‹ค. ๋‹น์‹ ์˜ ์•ฑ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋‹ค์„ฏ๊ฐœ์˜ ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉ์ž ์ธ์ฆ์„ ๋ฐ›๋”๋ผ๋„ ์ƒ๊ด€์—†๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ž์‹ ์˜ ์ฝ”๋””๋„ค์ดํ„ฐ์—์„œ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๋” ํฐ ์•ฑ์„ ์œ„ํ•ด์„œ๋Š”, ์ž์‹ ์ฝ”๋””๋„ค์ดํ„ฐ child coordinators(๋˜๋Š” ์„œ๋ธŒ์ฝ”๋””๋„ค์ดํ„ฐ subcoordinators)๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค - ์ด๊ฒƒ์€ ๋‹น์‹ ์˜ ์•ฑ ํƒ‘์ƒ‰์˜ ์ผ๋ถ€๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์–ด๋–ค ์ž์‹ ์ฝ”๋””๋„ค์ดํ„ฐ๋Š” ๊ณ„์„ฑ ์ƒ์„ฑ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๊ณ , ๋‹ค๋ฅธ ๊ฒƒ์€ ์ œํ’ˆ ๊ตฌ๋… ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋งŒ์•ฝ ๋” ๋งŽ์€ ์œ ์—ฐํ•จ์„ ์›ํ•œ๋‹ค๋ฉด, ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์™€ ์ฝ”๋””๋„ค์ดํ„ฐ ๊ฐ„์˜ ๋Œ€ํ™”๊ฐ€ ๊ตฌ์ฒด ํƒ€์ž…๋ณด๋‹ค ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง€๋„๋ก ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ์ƒ๊ฐ์ด๋‹ค. ์ด๊ฒƒ์€ ๋‚˜์ค‘์— ๋‹น์‹ ์ด ์ฝ”๋””๋„ค์ดํ„ฐ ์ „์ฒด๋ฅผ ๋‹ค๋ฅธ ํฌ์ธํŠธ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค„ ๊ฒƒ์ด๋ฉฐ, ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์„ ๊ฐ–๋„๋ก ํ•œ๋‹ค - ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹น์‹ ์€ ์•„์ดํฐ, ์•„์ดํŒจ๋“œ, ์• ํ”ŒTV ๋“ฑ์— ๋Œ€ํ•œ ๊ฐ๊ฐ์˜ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋”ฐ๋ผ์„œ, ๋‹น์‹ ์ด ๊ฑฐ๋Œ€ํ•œ ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ๋•Œ๋ฌธ์— ๊ณ ๊ตฐ๋ถ„ํˆฌํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ๋‚ด๋น„๊ฒŒ์ด์…˜(ํƒ์ƒ‰)์„ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ด์ œ ์ถ”์ƒ์ ์ธ ์ด์•ผ๊ธฐ๋Š” ์ถฉ๋ถ„ํ•˜๋‹ค - ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์ž.

์ฝ”๋””๋„ค์ดํ„ฐ ํ”„๋กœํ† ์ฝœ ๋งŒ๋“ค๊ธฐ

Coordinator ํ”„๋กœํ† ์ฝœ

import UIKit

protocol Coordinator: AnyObject {
    var childCoordinators: [Coordinator] { get set }
    var navigationController: UINavigationController { get set }

    func start()
}
  • childCoordinators : ์ž์‹ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์ €์žฅ
  • navigationController : ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ ์‚ฌ์šฉ๋  ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ €์žฅ.
    • ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋ฐ”๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๋”๋ผ๋„, ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด๋‹ค.
  • start() : ํ•ด๋‹น ์ฝ”๋””๋„ค์ดํ„ฐ๊ฐ€ ์ œ์–ด๊ถŒ์„ ๊ฐ–๋„๋ก ํ•˜๋Š” ๋ฉ”์„œ๋“œ. ์™„์ „ํžˆ ๋งŒ๋“ค๊ณ  ์ค€๋น„๋˜์—ˆ์„ ๋•Œ๋งŒ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ํ™œ์„ฑํ™”ํ•จ.
  • AnyObject : ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํ† ์ฝœ์ž„์„ ๋ช…์‹œ

์ฝ”๋””๋„ค์ดํ„ฐ ๋งŒ๋“ค๊ณ  ์‹คํ–‰ํ•˜๊ธฐ

MainCoordinator

์•ฑ ์‹คํ–‰๊ณผ ๋™์‹œ์— ์•ฑ์— ๋Œ€ํ•œ ์ œ์–ด๊ถŒ์„ ๊ฐ–๋Š” ์ฒซ ๋ฒˆ์งธ ์ฝ”๋””๋„ค์ดํ„ฐ.

์ž์‹ ์ฝ”๋””๋„ค์ดํ„ฐ๊นŒ์ง€ ์žˆ๋Š” ๊ฒฝ์šฐ, AppCoordinator๋ผ๊ณ  ์ด๋ฆ„์ง“๊ธฐ๋„ ํ•œ๋‹ค.

import UIKit

class MainCoordinator: Coordinator {
    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func start() {
        let vc = ViewController.instantiate()
                vc.coordinator = self
        navigationController.pushViewController(vc, animated: false)
    }
}
  • ํ•ด๋‹น ์ฝ”๋””๋„ค์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ๋ทฐ์ปจ๋“ค์— ์˜ํ•ด ๊ณต์œ ๋  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— struct๋ณด๋‹ค class๋กœ ์„ ์–ธ
  • Coordinator ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜
  • start() : ViewController ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , navigationController์— pushํ•œ๋‹ค.

โœ… MainCoordinator๋Š” ViewController๊ฐ€ ์•„๋‹ˆ๋‹ค.

(UIKit์— ์˜ํ•ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” viewDidLoad(), viewWillAppear()์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, UIViewController์˜ ๋‹จ์ ๊ณผ ์‹ธ์šธ ํ•„์š”๊ฐ€ ์—†๋‹ค.)

AppDelegate

์•ฑ์ด ์‹œ์ž‘ํ•  ๋•Œ ์œ„ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก AppDelegate์— ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.


// AppDelegate.swift

var coordinator: MainCoordinator? // <- ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋ฅผ ์•ฑ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ์— ์ถ”๊ฐ€

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // ์•ฑ์—์„œ ์‚ฌ์šฉํ•  ๋ฉ”์ธ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ƒ์„ฑ
    let navController = UINavigationController()

    // ๋ฉ”์ธ ์ฝ”๋””๋„ค์ดํ„ฐ์— ๋„ค๋น„๊ฒŒ์ด์…˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋„ฃ์Œ - ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด
    coordinator = MainCoordinator(navigationController: navController)

    // ์ฝ”๋””๋„ค์ดํ„ฐ๊ฐ€ ์ œ์–ด๊ถŒ์„ ๊ฐ–๋„๋ก ์ง€์‹œ
    coordinator?.start()

    // ๊ธฐ๋ณธ UIWindow๋ฅผ ๋งŒ๋“ค๊ณ  ํ™œ์„ฑํ™”ํ•˜๊ธฐ
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = navController
    window?.makeKeyAndVisible()

    return true
}
  • var coordinator: MainCoordinator?
    • ์•ฑ์˜ ๋ฉ”์ธ ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    • MainCoordinator๋ฅผ ๊ตฌ์„ฑ ๋ฐ ์‹คํ–‰
    • ์•ฑ์˜ ๊ธฐ๋ณธ window๋ฅผ ์„ค์ •
    • (์›๋ž˜ ๊ธฐ๋ณธ window๋Š” ์Šคํ† ๋ฆฌ๋ณด๋“œ์— ์˜ํ•ด ์„ค์ •๋˜์ง€๋งŒ, ์ด์ œ๋Š” ์šฐ๋ฆฌ์˜ ์ฑ…์ž„์ด๋‹ค)

์•ฑ์˜ ํ๋ฆ„ ์ฒ˜๋ฆฌํ•˜๊ธฐ

ViewController

  • ๋ชจ๋“  ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋“ค์€ ์ž์‹ ์˜ ์ฝ”๋””๋„ค์ดํ„ฐ์™€ ๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    • ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, (ํฐ ์•ฑ์˜ ๊ฒฝ์šฐ) - Advanced coordinators in iOS ์ฐธ๊ณ 
    • ์ฝ”๋””๋„ค์ดํ„ฐ๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ ์ง์ ‘ ์†Œ์œ ํ•  ์ˆ˜ ์žˆ๋‹ค (์ž‘์€ ์•ฑ์˜ ๊ฒฝ์šฐ)
      • weak var coordinator: MainCoordinator?

Coordinator๋กœ ํ™”๋ฉด ์ „ํ™˜

์ฝ”๋””๋„ค์ดํ„ฐ์— ํ™”๋ฉด์„ ์ „ํ™˜ํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ์‚ฌ์ด๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • start()์™€ ๊ฑฐ์˜ ๋น„์Šทํ•˜๊ฒŒ ์ƒ๊ฒผ์ง€๋งŒ, ๋ณด์—ฌ์ฃผ๋Š” ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅด๋‹ค
  • ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์— ๋Œ€ํ•œ ์–ด๋–ค ๊ตฌ์„ฑ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ์—์„œ ์ง„ํ–‰ํ•˜๋ฉด ๋œ๋‹ค.
// MainCoordinator์— ์ถ”๊ฐ€
func buySubscription() {
    let vc = BuyViewController.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}

func createAccount() {
    let vc = CreateAccountViewController.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}
  • ๊ทธ ๋‹ค์Œ, ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํ™”๋ฉด์„ ์ „ํ™˜ํ•ด์•ผ ํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ coordinator์˜ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ™”๋ฉด์ด ์ „ํ™˜๋œ๋‹ค.
// ํ™”๋ฉด์ „ํ™˜์ด ํ•„์š”ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ViewController์— ์ถ”๊ฐ€
@IBAction func buyTapped(_ sender: Any) {
    coordinator?.buySubscription()
}

@IBAction func createAccount(_ sender: Any) {
    coordinator?.createAccount()
}