
(
рдЪрд┐рддреНрд░рдг )
рдкреНрд░рддреНрдпреЗрдХ рдЯреАрдо рдЬрд▓реНрдж рдпрд╛ рдмрд╛рдж рдореЗрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддреА рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдкреНрд░рддрд┐рдпрд╛рдВ рдЯреВрдЯ рдЧрдИрдВред
рдЕрдореНрдмреНрд░реЗрд▓рд╛ рдЖрдИрдЯреА рдореЗрдВ рд╣рдо рд╣рдореЗрд╢рд╛ рд▓рдЪреАрд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рддрд╛рдХрд┐ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХреБрдЫ рджрд░реНрджрдирд╛рдХ рди рд╣реЛ, рдФрд░ рдиреЗрд╡рд┐рдЧреЗрд╢рди, рдореЙрдХ-рдлрд╛рдЗрд▓реНрд╕, рдЖрдЗрд╕реЛрд▓реЗрд╢рди рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ рдХреБрдЫ рдбрд░рд╛рд╡рдиреА рд╣реЛрдВ, рдХреБрдЫ рдРрд╕рд╛ рдЬреЛ рдЬрд▓реНрдж рдпрд╛ рдмрд╛рдж рдореЗрдВ рд╣реЛред рдПрдХ рдЕрддрд┐рд╡реГрджреНрдзрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рд▓рдЯрдХрд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рдПрдХ рдирдП "рдЕрдирдиреНрдп" рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдирд╛рдо рд╣реИред рдореБрдЭреЗ рдпрд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд▓реЛрдХрдкреНрд░рд┐рдп рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ (MVP, MVVM, VIPER, рдХреНрд▓реАрди-рд╕реНрд╡рд┐рдлреНрдЯ) рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдореБрдХрд╛рдмрд▓рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ рдЧрд▓рдд рд╡рд┐рдХрд▓реНрдк рдФрд░ рдЗрд╕ рдпрд╛ рдЙрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдЧрд▓рдд рдЙрдкрдпреЛрдЧ рд╕реЗ рдореБрд╢реНрдХрд┐рд▓реЗрдВ рдкреИрджрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдкрдирд╛рдпрд╛ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░, рд╡рд┐рднрд┐рдиреНрди рдкреИрдЯрд░реНрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдЙрди рдмрд╣реБрдд рд╣реА рдкреМрд░рд╛рдгрд┐рдХ рд╕рдВрдХреЗрддрдХреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛: рд▓рдЪреАрд▓рд╛рдкрди, рдЕрд▓рдЧрд╛рд╡, рдкрд░реАрдХреНрд╖рдгрд╢реАрд▓рддрд╛, рдкреБрди: рдЙрдкрдпреЛрдЧред
рдмреЗрд╢рдХ, рдЖрд╡реЗрджрди рдЕрд▓рдЧ рд╣реИрдВред рдпрджрд┐ рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреЗрд╡рд▓ рдХреБрдЫ рд╕реНрдХреНрд░реАрди рд╣реИрдВ рдЬреЛ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВ, рддреЛ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмреАрдЪ рдЬрдЯрд┐рд▓ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреА рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд╕реЗрдЧ-рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдпрд╣ рдЕрдЪреНрдЫреЗ рдкреБрд░рд╛рдиреЗ рдПрдорд╡реАрд╕реА / рдПрдорд╡реАрдкреА рдХреЗ рд╕рд╛рде рд╕рднреА рд╕реАрдЬрди рдХрд░рддрд╛ рд╣реИред рдФрд░ рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рд╕реНрдиреЛрдмреЗрд░реА рдЬрд▓реНрдж рдпрд╛ рдмрд╛рдж рдореЗрдВ рд╣рд░ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╣рд░рд╛ рджреЗрддрд╛ рд╣реИ, рдлрд┐рд░ рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рдХреНрд╖реНрдпреЛрдВ рдФрд░ рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рдЬрдЯрд┐рд▓ рд╕реНрдХреНрд░реАрди рд╕рдВрд░рдЪрдирд╛ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд░рд╛рдЬреНрдп (рдкреНрд░рд╛рдзрд┐рдХрд░рдг, рдЕрддрд┐рдерд┐ рдореЛрдб, рдСрдлрд╝рд▓рд╛рдЗрди, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рднреВрдорд┐рдХрд╛ рдЖрджрд┐) рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рддреЛ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓реАрдХреГрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдЪрд╛рд▓ рдЪрд▓реЗрдЧрд╛: рдмрд╣реБрдд рд╕рд╛рд░реА рдирд┐рд░реНрднрд░рддрд╛, рдПрдХ рдЕрд╕реНрдкрд╖реНрдЯ рдФрд░ рдорд╣рдВрдЧрд╛ рдбреЗрдЯрд╛ рд╕реНрдХреНрд░реАрди рдФрд░ рд░рд╛рдЬреНрдп, рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд - рдпрд╣ рд╕рдм рдХрд┐рд╕реА рднреА рд▓рдЪреАрд▓реЗрдкрди рдФрд░ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛, рд╕рдорд╛рдзрд╛рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХрд╕рдХрд░ рдкрд┐рдШрд▓ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рд╕реНрдХреНрд░реАрди рдП рд╣рдореЗрд╢рд╛ рд╕реНрдХреНрд░реАрди рдЦреЛрд▓реЗрдЧреАред рдмреА рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕ рджрд░реНрджрдирд╛рдХ рд░рд┐рдлреНрд▓реЗрдХреНрдЯрд░ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗрдВрдЧреЗред рдирдЧрдорд╛ рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рдЧрд▓рддрд┐рдпрд╛рдБ рдХрд░рдирд╛ рдФрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреА рдЧрдИ рдЪреАрдЬреЛрдВ рдХреЛ рддреЛрдбрд╝рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рдПрдХ рд▓рдЪреАрд▓реЗ рддрд░реАрдХреЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рджреЛ рд░рд╛рдЬреНрдп рд╣реИрдВ: рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдзрд┐рдХреГрдд рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕реНрдХреНрд░реАрди рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдзрд┐рдХреГрдд рд╣реИ рдФрд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдореБрдЦреНрдп рд╕реНрдХреНрд░реАрди рдЦреЛрд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
1. рдореБрдЦреНрдп рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдЖрдзрд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рд╕рдм рд╕рдордиреНрд╡рдпрдХ, рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп, рдирд┐рдпрдорд┐рдд рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ:
protocol Coordinatable: class { func start() } protocol Presentable { var toPresent: UIViewController? { get } } extension UIViewController: Presentable { var toPresent: UIViewController? { return self } func showAlert(title: String, message: String? = nil) { UIAlertController.showAlert(title: title, message: message, inViewController: self, actionBlock: nil) } }
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, showAlert рдПрдХ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рд░реНрдл рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рд╣реИ, рдЬреЛ рдХрд┐ UIViewController рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рд╣реИред protocol Routable: Presentable { func present(_ module: Presentable?) func present(_ module: Presentable?, animated: Bool) func push(_ module: Presentable?) func push(_ module: Presentable?, animated: Bool) func push(_ module: Presentable?, animated: Bool, completion: CompletionBlock?) func popModule() func popModule(animated: Bool) func dismissModule() func dismissModule(animated: Bool, completion: CompletionBlock?) func setRootModule(_ module: Presentable?) func setRootModule(_ module: Presentable?, hideBar: Bool) func popToRootModule(animated: Bool) }
2. рдПрдХ рд╕рдордиреНрд╡рдпрдХ рдмрдирд╛рдПрдБ
рд╕рдордп-рд╕рдордп рдкрд░, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдХреНрд░реАрди рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдбрд╛рдЙрдирдбрд╛рдЙрди рдХреЗ рдмрд┐рдирд╛ рдкрд░реАрдХреНрд╖рдг рдкрд░рдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рд╕рд╛рде рд╣реА рд╕рд╛рде SOLID рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд┐рдП рдмрд┐рдирд╛ред
рд╣рдо рд╕рдордиреНрд╡рдп рдкрд░рдд рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ:

рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, AppCoordinator рдкрджреНрдзрддрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХреГрдд рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдкреНрд░рд╡рд╛рд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓рд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдкреНрд░рд╡рд╛рд╣рд┐рдд рдХрд░реЗрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, MainCoordinator рдФрд░ AuthorizationCoordinator рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╣рдо рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕рдордиреНрд╡рдпрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ, рдЕрдиреНрдп рд╕рднреА рд╕реНрдХреНрд░реАрди рдПрдХ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рдмрдирд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рд╕рдордиреНрд╡рдпрдХ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡рд╣ рдПрдХ рдЙрдЪреНрдЪ рд╕рдордиреНрд╡рдпрдХ (AppCoordinator) рдХреЗ рд╕рд╛рде рдПрдХ рдХрдиреЗрдХреНрд╢рди рд░рдЦ рд╕рдХреЗ:
protocol AuthorizationCoordinatorOutput: class { var finishFlow: CompletionBlock? { get set } } final class AuthorizationCoordinator: BaseCoordinator, AuthorizationCoordinatorOutput { var finishFlow: CompletionBlock? fileprivate let factory: AuthorizationFactoryProtocol fileprivate let router : Routable init(router: Routable, factory: AuthorizationFactoryProtocol) { self.router = router self.factory = factory } }

рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд░рд╛рдЙрдЯрд░ рдФрд░ рдПрдХ рдореЙрдбреНрдпреВрд▓ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕рдордиреНрд╡рдпрдХ рд╣реИред рд▓реЗрдХрд┐рди рдХреМрди рдФрд░ рдХрдм рдкреНрд░рд╛рд░рдВрдн () рд╡рд┐рдзрд┐ рдХрд╣рддрд╛ рд╣реИ?
рдпрд╣рд╛рдВ рд╣рдореЗрдВ AppCoordinator рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
final class AppCoordinator: BaseCoordinator { fileprivate let factory: CoordinatorFactoryProtocol fileprivate let router : Routable fileprivate let gateway = Gateway() init(router: Routable, factory: CoordinatorFactory) { self.router = router self.factory = factory } } // MARK:- Coordinatable extension AppCoordinator: Coordinatable { func start() { self.gateway.getState { [unowned self] (state) in switch state { case .authorization: self.performAuthorizationFlow() case .main: self.performMainFlow() } } } } // MARK:- Private methods func performAuthorizationFlow() { let coordinator = factory.makeAuthorizationCoordinator(with: router) coordinator.finishFlow = { [weak self, weak coordinator] in guard let `self` = self, let `coordinator` = coordinator else { return } self.removeDependency(coordinator) self.start() } addDependency(coordinator) coordinator.start() } func performMainFlow() { // MARK:- main flow logic }
рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ AppCoordinator рдореЗрдВ рдПрдХ рд░реВрдЯрд░, рдПрдХ рд╕рдордиреНрд╡рдпрдХ рдХрд╛рд░рдЦрд╛рдирд╛ рдФрд░ AppCoordinator рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХреА рд╕реНрдерд┐рддрд┐ рд╣реИ, рдЬрд┐рд╕рдХреА рднреВрдорд┐рдХрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡рд╛рд╣ рдХреА рд╢реБрд░реБрдЖрдд рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред
final class CoordinatorFactory { fileprivate let modulesFactory = ModulesFactory() } extension CoordinatorFactory: CoordinatorFactoryProtocol { func makeAuthorizationCoordinator(with router: Routable) -> Coordinatable & AuthorizationCoordinatorOutput { return AuthorizationCoordinator(router: router, factory: modulesFactory) } }
3. рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд╕рдордиреНрд╡рдпрдХреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рд╕рдордиреНрд╡рдпрдХреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдПрдХ рд░рд╛рдЙрдЯрд░ рдФрд░ рдПрдХ рдореЙрдбреНрдпреВрд▓ рдлреИрдХреНрдЯреНрд░реА рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рд╕рдордиреНрд╡рдпрдХ рдХреЛ рдЖрдзрд╛рд░ рд╕рдордиреНрд╡рдпрдХ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП:
class BaseCoordinator { var childCoordinators: [Coordinatable] = [] // Add only unique object func addDependency(_ coordinator: Coordinatable) { for element in childCoordinators { if element === coordinator { return } } childCoordinators.append(coordinator) } func removeDependency(_ coordinator: Coordinatable?) { guard childCoordinators.isEmpty == false, let coordinator = coordinator else { return } for (index, element) in childCoordinators.enumerated() { if element === coordinator { childCoordinators.remove(at: index) break } } } }
рдмреЗрд╕рдХреЙрд░реНрдбрд┐рдиреЗрдЯрд░ - рдПрдХ рд╡рд░реНрдЧ рдЬрд┐рд╕рдореЗрдВ рдмрд╛рд▓ рд╕рдордиреНрд╡рдпрдХ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реЛрддреА рд╣реИ рдФрд░ рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реЛрддреА рд╣реИрдВ: рд╕рдордиреНрд╡рдпрдХ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд╣рдЯрд╛рдПрдВ рдФрд░ рдЬреЛрдбрд╝реЗрдВред
4. AppDelegate рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛
рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐
UIApplicationMain рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛
рд╣реИ: @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var rootController: UINavigationController { window?.rootViewController = UINavigationController() window?.rootViewController?.view.backgroundColor = .white return window?.rootViewController as! UINavigationController } fileprivate lazy var coordinator: Coordinatable = self.makeCoordinator() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { coordinator.start() return true } }
рдЬреИрд╕реЗ рд╣реА рдкреНрд░рддрд┐рдирд┐рдзрд┐ рд╡рд┐рдзрд┐ didFinishLaunchingWithOptions рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, AppCoordinator рдХреА рд╢реБрд░реБрдЖрдд () рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЖрд╡реЗрджрди рдХреЗ рдЖрдЧреЗ рдХреЗ рддрд░реНрдХ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ред
5. рдПрдХ рд╕реНрдХреНрд░реАрди рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдирд╛
рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд╛рдкрд╕ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ PerformFlow () рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ ModulesFactory рд╡рд░реНрдЧ рдореЗрдВ AuthorFFactoryProtocol рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
final class ModulesFactory {} // MARK:- AuthorizationFactoryProtocol extension ModulesFactory: AuthorizationFactoryProtocol { func makeEnterView() -> EnterViewProtocol { let view: EnterViewController = EnterViewController.controllerFromStoryboard(.authorization) EnterAssembly.assembly(with: view) return view
рдПрдХ рдореЙрдбреНрдпреВрд▓ рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдХрд┐рд╕реА рднреА рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдХрд░, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕реНрдЯреЛрд░реАрдмреЛрд░реНрдб рд╕реЗ рд╡реНрдпреВрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рдФрд░ рдлрд┐рд░ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдХреЛрдВ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ (MVP, MVVM, CleanSwift) рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рдирд╛ред
рдЖрд╡рд╢реНрдпрдХ рддреИрдпрд╛рд░реА рдХреЗ рдмрд╛рдж, рд╣рдо рдСрдерд░рд╛рдЗрдЬреЗрд╢рди рдХреЛрдСрд░реНрдбрд┐рдиреЗрдЯрд░ рдХреЗ рдкрд░рдлреЙрд░реНрдореЛ () рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЗрд╕ рд╕рдордиреНрд╡рдпрдХ рдХреЗ рднреАрддрд░ рдкреНрд░рд╛рд░рдВрдн рд╕реНрдХреНрд░реАрди EnterView рд╣реИред
PerformFlow () рд╡рд┐рдзрд┐ рдореЗрдВ, рдореЙрдбреНрдпреВрд▓ рдлреИрдХреНрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рджрд┐рдП рдЧрдП рд╕рдордиреНрд╡рдпрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдПрдХ рдмрд╛рд░ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкрд░ рд╣рдорд╛рд░реЗ рд╡реНрдпреВ рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЛ рд░рд╛рдЙрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╕реНрдХреНрд░реАрди рдХреЗ рдиреЗрд╡рд┐рдЧреЗрд╢рди рд╕реНрдЯреИрдХ рдореЗрдВ рд░реВрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
private extension AuthorizationCoordinator { func performFlow() { let enterView = factory.makeEnterView() finishFlow = enterView.onCompleteAuthorization enterView.output?.onAlert = { [unowned self] (message: String) in self.router.toPresent?.showAlert(message: message) } router.setRootModule(enterView) } }

рдХреБрдЫ рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рдкреНрд░рддреАрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдпрд╣ рдкреИрдЯрд░реНрди рдореЙрдХ-рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрджрд░реНрд╢ рд╣реИ, рдЖрдкрдХреЛ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ UIKit рд╕реЗ рднреА рд╕рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдкреВрд░реНрдг рдкрд░реАрдХреНрд╖рдг рдХрд╡рд░реЗрдЬ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓ рд╣реИред рдЗрд╕реА рд╕рдордп, рд╕рдордиреНрд╡рдпрдХ рдЖрд╡реЗрджрди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдкрд░ рд╕рдЦреНрдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЬреЛрдбрд╝, рд╕рдВрд░рдЪрдирд╛ рдиреЗрд╡рд┐рдЧреЗрд╢рди, рдирд┐рд░реНрднрд░рддрд╛ рдФрд░ рдбреЗрдЯрд╛ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдмреАрдЪ рдмрд╣рддрд╛ рд╣реИред
рдЬреАрдердм рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВ , рдЬрд┐рд╕рдореЗрдВ рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдбреЗрдореЛ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рд▓ рд▓реЗрдпрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ Xcode рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╣реЛред