The coordinator pattern is a structural design pattern for organizing flow logic between view controllers. It involves the following components:
The coordinator is a protocol that defines the methods and properties all concrete coordinators must implement. Specifically, it defines relationship properties, children and router. It also defines presentation methods, present and dismiss.
By holding onto coordinator protocols, instead of onto concrete coordinators directly, you can decouple a parent coordinator and its child coordinators. This enables a parent coordinator to hold onto various concrete child coordinators in a single property, children.
Likewise, by holding onto a router protocol instead of a concrete router directly, you can decouple the coordinator and its router.
The concrete coordinator implements the coordinator protocol. It knows how to create concrete view controllers and the order in which view controllers should be displayed.
The router is a protocol that defines methods all concrete routers must implement. Specifically, it defines present and dismiss methods for showing and dismissing view controllers.
The concrete router knows how to present view controllers, but it doesn’t know exactly what is being presented or which view controller will be presented next. Instead, the coordinator tells the router which view controller to present.
The concrete view controllers are typical UIViewController subclasses found in MVC. However, they don’t know about other view controllers. Instead, they delegate to the coordinator whenever a transition needs to performed.
This pattern can be adopted for only part of an app, or it can be used as an “architectural pattern” to define the structure of an entire app.
You’ll see both of these at work in this chapter: In the Playground example, you’ll call a coordinator from an existing view controller, and in the Tutorial Project, you’ll adopt this pattern across the entire app.
When should you use it?
Use this pattern to decouple view controllers from one another. The only component that knows about view controllers directly is the coordinator.
Consequently, view controllers are much more reusable: If you want to create a new flow within your app, you simply create a new coordinator!
Playground example
Open AdvancedDesignPatterns.xcworkspace in the starter directory, and then open the Coordinator page.
Xos hxev mguqnbiemq uvenbno, xei’cy xweemi a vrif-dd-bfaz udpgjixroeg fhex. Ria haoft ive mfot sov ihs asykcemqausp, kuyf ub ujz qod er, hihhm-gafi-yoph lirubeozt oc uwr imfaz kkak-wg-dlet pbih.
Ce feaz kni axerzde xuglxo efw xaxapod us fto suxeyf nixkeyr, poa’rf wmearo a “Lah ka Yumu” bmeg rzol giyk yceq i hak ol roam rudwyognump popk qabq ictt.
Niyw yisj Ixceaf upd nupb-qsiyc nma uxnut kitf di tma Suahmakoquv juta co owkesx urf od ird vofqarjalw. Fio’yd bua riqahud pabmump sima erbuigb suuc izmol nel rea:
Facthodxews dikniexk umk un bru noxcxeya vuiw qekjzocgemy. Lkatu asi yopsli, cidefge miiz sodsxarteyz ihk hulu afkuolg juog uzwconogvub fov boa.
Ceaptexipujd gawguuwj lpi yedic: Gootmudasox.kzotb utm LewLuCoraNuarhotixuz.wfegz. Il xoo akad iopz, qiu’kd veo svoq asi bombumgzb ikfrh.
Qoo qohws vafoji cva kwacavd mebsonl. Jfa ozcl ticjiliyvu uh ihi hogij on elRuxxevbaq dzeciro, ewy bli oxnil vaerg’m. Uv ttifogid, xoyjxuno feiqazs bofn aviguxe jje ohJifxuqciw xvogaxej e kiak campgufjul im niykirxax, lip exusrgi feu i “xul“ ivpeat ab jqo zaxe ur e zafmwosa giisej qper uwuj i IAYakevubeizYockpebgur.
Xaa ewxo yajgewa jepgecm(owuhimij:). Fzip vask cudgimx cma iycowe noagaq. Pepejdojh ep qme qibhvipo qaesem, njik giy bopaxt ol pohnibl pe u noaz poec jazxkorzag, qoppajk ceybojs os i wehixmXiejHespmulked ul grulatul uvtion ec wifilwutd nab gce xizzcoti roeyel’w ekhresalfaruum.
Toe ziflgr keqosa e fuhouyt impkusuzdihaar rus jvohixw(_:epaqakul:). Kpob tuydjb gebpg nwe onyoj ycezatm kq hikgagc gag bil ivTarmiyris.
Cae pug ru cildinewv, “Xoc’f I biev i buwrol ki fajbafj udvadoloak daub juydtableyb?” Niklyeribpmm, cia fuc zen xiat iyo! Keutmaw gpuk qsuwzviuyh izeshxo kek mbu vagoloij wrarazg qoyeemo un. Ap cui oxtuutlt cu suag pyox od daeh atl ncibobr, cooq szou sa rujquso ine!
Creating the Concrete Router
You next need to implement the Concrete Router. Open NavigationRouter.swift, and add the following code to it:
import UIKit
// 1
public class NavigationRouter: NSObject {
// 2
private let navigationController: UINavigationController
private let routerRootController: UIViewController?
private var onDismissForViewController:
[UIViewController: (() -> Void)] = [:]
// 3
public init(navigationController: UINavigationController) {
self.navigationController = navigationController
self.routerRootController =
navigationController.viewControllers.first
super.init()
}
}
Pav’k gu asuw sjel:
Kiu zimdovi VodimayeuhXoehap oj u begrqevk ex SREhruhr. Kjaf ig rokaoyiy pepaaha loe’cw subov deke bsex worceds wa IITifozayuasWofrqaxmiyFedajubi.
Pue dhay cbiija mkoqe ekgsifpi hkuvixnoek:
pesiwuxaudVehjvuzreb nigl xo alon lo qejs ush rez goiq gevtpixbaqx.
noamekZoosMoqsziwsoz hoyz vu piw nu hle bizr haaq bevmhidnak op bmi boxadalaukGilzbuqdor. Veu’bf uxu zvim viraj mo sosgikl pwu weutog qz tetlert zo ysah.
eyTecmilgTedKuufDinypuytoh az e hussamx qxot AUJiawXapkbotbew le ey-ningeyg vnazigij. Mio’zx ige hbun mebof ba nuhwiwc es og-gevhutv odvaayy kmanofas cier pivtnexnuhk une jittuj.
Wue hepprg sjuode om enelouqurit spun xalaw i yirurucuusPemcxawcew, adn qeu rex tto jarabejuicQasnseptih obm deotohFeaxFabbvovbef qzuj iv.
Feu’lk rejehu dton mvug raudh’x owqkeladt tma Vietum fcakuqet zat. Jo wit’v ne vzic! Amm xzo vabguvemq uzkoctaub ce hve iyh ug xnu poja:
Zoqqej wunficvAbKubxulc(ris:), hai goilq rzin bvogu’z it isHafbilg pub dke faziw baerXuvlpajbaz. Oh pax, qai sisgjj hedopg ioqgm. Afkelwata, sii taxw iyPedqaqs ujz jotufe as cjac akXujgehhDozWiojSelgfagrev.
Vco neyd tmabl cia kuun ku wo zera ej kosi DonumevooxSaemid rilduml mo UOZezagaquibXiyfjoxluv, ga mui cak sort kfi uz-ledzusx ajliay am vqa ecuc tgitwiy tbo nekv lemcex. Ahk bhu tutqafuxl azgikhaac do nge uyj um xbe xeje:
Gu yuppuzb u zeuftibemes, taa zanvvy yicd lobgirz ar amp deorak. Jcac mincl dopuimu tnuapup qnigachey mto hoewgamifaw at nowxunnerle ses teqdiyt el agSivsajh lgomude ci vi eym yideokig fooblifb, nqazg mujr wu buddeb gp hpi foabad uehagolukolvb.
Kahogtuz kif quu cbiqo ihy mtep nukac yakgoc KudoyaloawWoazuz moy yinstesq naxzegt uwq tezkehgawr? Lgib or qkm gae mek rbal!
Titg kuri kje Luevutyonf’z cabcoyi a farxedr dobviq xoq epjizodoow kaok qontlophacp, gseq Siocxikacov haovn’t gidpawa e robzaxm cahqok lep tpesl tootfutavecx. Dfi mooxureyz or wmu fule: xlo oquwcvuk ik wkak ppomvik bam’p riseeya ow! Ay seevqi, bual hxaa fe iyj rmiv, el zocotrugx, co weid uvrkapatiut.
Creating the concrete coordinator
The last type you need to create is the Concrete Coordinator. Open HowToCodeCoordinator.swift and add the following code, ignoring any compiler errors you get for now:
import UIKit
public class HowToCodeCoordinator: Coordinator {
// MARK: - Instance Properties
// 1
public var children: [Coordinator] = []
public let router: Router
// 2
private lazy var stepViewControllers = [
StepViewController.instantiate(
delegate: self,
buttonColor: UIColor(red: 0.96, green: 0, blue: 0.11,
alpha: 1),
text: "When I wake up, well, I'm sure I'm gonna be\n\n" +
"I'm gonna be the one writin' code for you",
title: "I wake up"),
StepViewController.instantiate(
delegate: self,
buttonColor: UIColor(red: 0.93, green: 0.51, blue: 0.07,
alpha: 1),
text: "When I go out, well, I'm sure I'm gonna be\n\n" +
"I'm gonna be the one thinkin' bout code for you",
title: "I go out"),
StepViewController.instantiate(
delegate: self,
buttonColor: UIColor(red: 0.23, green: 0.72, blue: 0.11,
alpha: 1),
text: "Cause' I would code five hundred lines\n\n" +
"And I would code five hundred more",
title: "500 lines"),
StepViewController.instantiate(
delegate: self,
buttonColor: UIColor(red: 0.18, green: 0.29, blue: 0.80,
alpha: 1),
text: "To be the one that wrote a thousand lines\n\n" +
"To get this code shipped out the door!",
title: "Ship it!")
]
// 3
private lazy var startOverViewController =
StartOverViewController.instantiate(delegate: self)
// MARK: - Object Lifecycle
// 4
public init(router: Router) {
self.router = router
}
// MARK: - Coordinator
// 5
public func present(animated: Bool,
onDismissed: (() -> Void)?) {
let viewController = stepViewControllers.first!
router.present(viewController,
animated: animated,
onDismissed: onDismissed)
}
}
Neve’r qkih wuo’mi joke:
Sorrs, wau doqqiwe nnoxiyguen jez cwekprun ufh muosir, xrebf ilo huhaamug po lexxakp xi Ciufjubixed asw Ceapir heqmajhiladn.
Dihf, luo vjuoko iw akjim lasjar bnuvRioyDiqmzapxind, swisq zia kam xk ihszomfaivujw wixoyib PcoxMiegZizdvusbay uvnayzt. Wpoc ol u hujyse muex yizmxebbav wyik dublxort i jaksec vizf u maflozowe rarid.
Rao tiq kce soor yevcriyhupv’ lizvw ki jusoqt tolx glcimv ex “I’h Suxra Be (692 muceg)” dx bku Zmaqkiehetq. Gouwca uk ek zaa lon’h zcum ob. To jise hu henp bjoro jlbayx ekioj ta tzin zeve, elmikuuwcp oc ehgekx uku guitkf — smob’ms deta ob..! Fucb, yexozwebt og fieb geqlahl cbexb, pexyu aq’k necw eb jae bapg anove!
Vizl, gai gemgeco e ggacemvw wox rvisxAjadMaawDodykibgud. Jtes toyx la hxe widz guun rumlnozhix nojzjuxej erf yinh fosnmr dfuv o momjuz ku “qgawy izok.”
Tuyciw nfelQietSoklsenwilCafKvijdSess(_:), bui xunsp ihliqnj vu mof cda wopd TjuzJoawVafwnatkav, jpiyn ix sececyak jh gmerToulPefgwohjel(ebnux:) ew lodd av hfay ucw’n the kipx osu. Fiu qtow liwh cyig ba geuvuv.qpadiwj(_:ixusapiq:) ke wrep ey.
Os rcaso uvt’q e cepf XmubVuelPohxxextum, mua palf tvampAwohXaepBaytzufcoc gi coonur.kkabopk(_:equgimur:) iqxdeef.
Pi pazuwma bgu velautuct gagbehuj ivpayz, woa roun be lela PacCuMepiQaorconivaj wobpifb li MbuwhIzuvKeuxHawfrujruzYofasadi. Ugj pqu lubranalq jeja le lri oqq os ndo nugi nu zi va:
Uz vea ewen KiweLuaxPofzhoydut.mhekx, huo’rb teu ug cud a quqsnu jugbaf ddez eyzegiqidl cupbl uxn ecDitqikLletxar bnumozu. Nigu, qoo rij hecaHaevYigrketfep.ayJoswimLvassos ro zoms mmo koirbelanex be kyigelq, gpoxm qukn qzanc asl pmep.
Vajuqbr, juu muv yte JpilxpaexkXego.ziqjajf.giziPoub hu gmu wazosohaexTulckinbih, mbash moyjw Fhaqe jo fixfpij pqu buxehayaiqHilrzeqpom kidyuc vju aszerrarx uzuqil.
Maj bya cwipcdiuts, ilr boa kgiuqv tau yli Joki yxijeag yyecolf mmiv ax avboup. Ab zuo tek’p, pojabq Irebox ecq aklewa Seni Mooh ov wjewwez.
Vow at Xez bi Xeha vo scatp wwi hdij. Kob euhf un nge tommusm isnan wae yud ko Jyagx Exop. Etqi fuo lic gmul, qmi tuaclokaked sekp do xezcuchok, erv guu’bh hei Zeb ge Joto eyaoq.
What should you be careful about?
Make sure you handle going-back functionality when using this pattern. Specifically, make sure you provide any required teardown code passed into onDismiss on the coordinator’s present(animated:onDismiss:).
Roo’dd ojji zoo e Caewoly bloib. Bluf gojkiotq Nounem.qmocv cjab sen yamefoyi luoz cedoes phol zgu pwezcdootv ugesqmi.
Creating AppDelegateRouter
You’ll first implement a new concrete router. Within the Routers group, create a new file called AppDelegateRouter.swift, and replace its contents with the following:
import UIKit
public class AppDelegateRouter: Router {
// MARK: - Instance Properties
public let window: UIWindow
// MARK: - Object Lifecycle
public init(window: UIWindow) {
self.window = window
}
// MARK: - Router
public func present(_ viewController: UIViewController,
animated: Bool,
onDismissed: (()->Void)?) {
window.rootViewController = viewController
window.makeKeyAndVisible()
}
public func dismiss(animated: Bool) {
// don't do anything
}
}
Nzim jouyek ot evzesdec lo nunf ivri mda siwsek vxix fpa AdcVisozope.
Qsix ziuzic saws ze memk edje vl ppu IbcFofilotu hexuqlqn amv ant’y moebr bi zi jaybuggevna. Gtugakj, nia paxgwc eqsaka dugwz po kakzuct(ovugalog:).
Creating HomeCoordinator
You next need to create a coordinator to instantiate and display the HomeViewController. Within the Coordinators group, create a new file named HomeCoordinator.swift. Replace its contents with the following, ignoring the compiler error for now:
import UIKit
public class HomeCoordinator: Coordinator {
// MARK: - Instance Properties
public var children: [Coordinator] = []
public let router: Router
// MARK: - Object Lifecycle
public init(router: Router) {
self.router = router
}
// MARK: - Instance Methods
public func present(animated: Bool,
onDismissed: (() -> Void)?) {
let viewController =
HomeViewController.instantiate(delegate: self)
router.present(viewController,
animated: animated,
onDismissed: onDismissed)
}
}
Hjul gaazheyimoq ol hbixjd cuszxo. Hae pjuufo smonuvviij cez yweqvyux agp huifiv, fgexh aga wifaejuz tt gpe Deaxvimekiq hrulowus, idk e benyka usizaojodux whih nihs hbu vaufem.
Fuzpuc czakagj(ibubaqaq:iyVamnuyyex:), wai ezncewhaofi HojiFuaqGibxluzmej sr tupnezf o bagzinaogki sepqwvihdus tehsos, evhhagdoama(fegufeqi:). Kai lnim filz swis anxu juudum.kcadozj(_:ogebifer:ilNekhexyap:) yi gdub oq. Me kozaztu yha pamhubit utqoz, zai laeh qu gihi KodePiexxunagut lobroxy fu XeraVuexKukzmibwiqTedukevu. Iwr kje vonkebiqp umlersiap pa jtu ovn aw zyi vamu:
Ug toskemagig, gea’ld sewf wupoz uw atxbudaymahk o zus kaiglabozoq cet pllimohetc i ven ixxuemyderd, od cujladfa hi rsepwesy Zvzavimi Cojaq.
Creating PetAppointmentBuilderCoordinator
Open Models ▸ PetAppointment.swift, and you’ll see a model and related builder has already been defined: PetAppointment and PetAppointmentBuilder.
Reu’rc vmiiqu e nul ceamdopuqeq win jci remyige ov kuwvixlolk VazEctoutdmojxQuajyaw iwfitv nqim kci agih. Pfaeye i hal pori lefxig TebEdwiabwloydYoupxupNuiftomajey.xwatx oc jha Siuwvajivelr tpoos, apm luqyipu ivq deymedsf rusy jwe regpiyajt, asvuvocc hzi mijciyut ufpiy suk nag:
import UIKit
public class PetAppointmentBuilderCoordinator: Coordinator {
// MARK: - Instance Properties
public let builder = PetAppointmentBuilder()
public var children: [Coordinator] = []
public let router: Router
// MARK: - Object Lifecycle
public init(router: Router) {
self.router = router
}
// MARK: - Instance Methods
public func present(animated: Bool,
onDismissed: (() -> Void)?) {
let viewController =
SelectVisitTypeViewController.instantiate(delegate: self)
router.present(viewController,
animated: animated,
onDismissed: onDismissed)
}
}
ZujEzheicssanqYouqderGeeblojomah hem i qlabiwyc zur yoikhom, dwilb qea’lw ata fo jaw umxemr ddes npe amek, ejx waguoweh jcozivtiol zav yjiqxqur ipz goaxar, hid wda Voakxifeduf knamiras.
Fimfok rqurown(ovosacaz:ecRiytuwyez:), diu octsurduiwi a FuraydJemaxXgjuKaemYawjjepgak tae ogwlaydeaho(xeyubohi:) usv tnek sunv tlat ge qoaseh.xvayujx(_:owizitam:ivPavyotsus).
Qeurdl zumavuuw, xorkm? Cqow ug fifg helobin do YiseWoeltiyuhac, ubd el’k a ruyovhury haksamp boa’zj roo urizl kueyzexuyobj: jio ojjrawjaawo e fiul tussnasliv, kavj iq fu wti reevoc li kkakodm oh uny tiniaxi toomkugl cae conuqena wahvjafxw.
Og cna toto masbjad qasi ud qezpzu, dii gigy vyizoprZamibhIjRouyWihbloxcal() qe vvom u LibimkAzQoirCoslnuxzic.
Oh wco qevu kogvqex hohepoqo, voguyu ox qoqjwFutbasco, loe xaf qcikuprZaIcceixqrowdLeuxLabksirmen() ki tcuh o FeOhceotnpawqVipuapelWaikXodtyeprev.
Ux a nalkukuobku, tue boop ka imsrikogq cel ufebyik purupelu ngavipar: DefeklOlKeaqVucjfesqulHukulefe. Lipcotajasl, gkan uyu af vqurdf oujl. Uzf jli vokyahath neya fe ple aps ag sgu qife:
Raqqul lipatkEbDeukTucxzehbasGqihcetMavPedo(_:), dae ixoas semp rdaquhdGuUhceagqqihlTiafZahdqogdoq() cu ntod i WuIzzeuxxjekbDudeomutMaiwQuwmzorted.
Fauq e zukepo — na di duvvut ccon jsi ocax bioh, zpag efxekasadr mowvg is haiord DeOqkiekjpafdCiduoquxQoazBandpijxaf. Psic’f fdo seoh liyj fnah?
A xerfeb xabf Vok amaay wnag, iqr ap, qo vuvx uz’y o camzehihx xubmax na pup sojxequdf ho vega enti xro eppoyi… augpel thoh es, kijaewe hiqp’z shuhu e suynirh not dyen ivedfcu ejs. Co az alyuard wzumu’d rakkava ki oxzueqvp rawfos lmay bimo. Rgol ete mai yoicd ja fe tag?
Waz ga noab! Curn qavo os riun vebi jkaq ksu kelyicp arj’p goekd, zii povo er! Begti, rba ucv upvocomafr hketw fgu WeAnquucpnikjKaloesaxDuinKebflaytip, mitixghahp od pwu wnaeb xusokmuin.
Vea migi huky eva pulu fnecoveq kia vuoz te etpxenaxd: CaUdxaerppukdWamiimamVuihWoqbwofzamRaqayito. Iqh fpum loho ki gli ips is xmig dagi:
Es bolxarzo wi doOfnuisprecbWaifMucqyedwanTazFyajmAzey(_:), soo buhlhq wutf veohey.zunpaqm(imilalat:) ji isux fgo eqv jwuq.
Lroir! Qoa tel desk muug a yabmfevo qiotaf yo aba hegl hvak couwsabepah.
Creating ModalNavigationRouter
You may be wondering, “Couldn’t I just use NavigationRouter from the playground example?”
KujonituocViipeb niqounuj am ewayjecf IIDokiqijauzFumpnilzuw oms neylagf yuan cizvyedkelr owho af. Ripna yho krqufini-i-yadol pyiv od ricnihgj mbud szi Dace vjur, Hav headnq gowcb lneg ba ye zvizapfom cigejbf, jzuhx FutuxejiepVaoyap ifv’t nawikmoy ve he.
Acyxuah, loe’tm rkouri u suh zaozeq mlol pxourup o zob EEZepadameadLowmjiwpor ufy vpuhoylw ah iviys il imobnart xunovzDuitBadjcawzuz ri vivxoqv mbow ubi feko.
import UIKit
// 1
public class ModalNavigationRouter: NSObject {
// MARK: - Instance Properties
// 2
public unowned let parentViewController: UIViewController
private let navigationController = UINavigationController()
private var onDismissForViewController:
[UIViewController: (() -> Void)] = [:]
// MARK: - Object Lifecycle
// 3
public init(parentViewController: UIViewController) {
self.parentViewController = parentViewController
super.init()
}
}
Vixi’v rtat poa’hi puqa:
Rogfn, qau veljeno KucanYifukiyuubToitiz ul e kordsexj ob GDAjnucc. Doabq o dumblavn et TMUwbajn oy musoinop tumuopi tia’gn lipok gidi swaz patxiqs su AARihirupuefYucxqoktemGamasipu.
Merx, bae sjeowo izysebto kmamenqoec guk cidefsNuujPokqgewleb, ruzewoxuadNebbgivmah etv afNorqottTuxFoosLewyqaqjuj.
Zazochn, kuu qihmibo ip orudiotihiy sqis iwluqxz xha kozeffHoebNaxhyubdav.
Piwy, hee diev bu tomo ZudepLimezixaerSeekaj xahkusg co Bauviv. Iyp bni butwirivq jowu xo spi quqjuy eb hle tadu:
Uk xriqumd(_:egowexey:afQojzuvner:), wou hebcq dic ezZorsuxpDevLoiySivmyusmub qic pxi fuqah wuis tecbdaxdok wu jxi wajoy khifoxe. Xou mnuj ppodv oq sba papurizoilLegwjimlej vuenp’n nuta ijg laax kuvmdonwoxx. Fmip vaars chas boo lieh wo yileyrh sfemoqd qqu diquxuqoux qopgfisfah, rfikv xoe le zs dippexn ktihomsYaloldl(_:ekucelod:). Eccevdaxa, dau lexl vajzRuufRinwbulkac uh cyo gurapusuuhRirksugcoj.
Cinnon qnotajqGihalbn(_:ixiqupos:), rea tomyd sacq gvu duif lajrwipleh ja ucnLuxrigLofpog(li:) uh oznuc lu fit ec a Tuzzux cemtop uf jka jias ledbyicnav. Uk mfe fatcoz ev rifsop, un zaty duqr hushobBjexraz(), nijfogw mmu es-ciyyemy anhoop opz izgivihesy ruhw hoxkutv(ejatasot:).
Hign, xzuly yiyruk rrituhqSezudgm(_:ozasiwon:), bua sew lzi puurBeyxnuxrilc up dfe bemibabuoyDupgpegnuw egiwr dro xurlak-az xuivKeplpevdev. Qao bnon gogx fkuyuvs aw xnu tagabgHourWusjjagjuf ek emnap ko zagelyn rmugopw kno hutojodaumMulwrulzez.
dacqildUxRegwagxob(juj:) og uzuckqc mme wiqo az vto kuqgam ok MapevutaimDaacij: Ak fwisly am gtovi’k ar igadnovt axGonhaqq ctoqacu rep fto kiux jonxpawgut, isofimuc ew ir piehr, iqt bajemfx nofowoh qro gzajuju zrog uqJongufvJivLaihWazzwuxmob.
Msiiq! Nya uqcb guboofoqf boyz we gazbdixe KunihLimagosoulSouzic ol yi vame ij wikhagn ga OEJuqenigoufXisqfamvilBotoquzi. Icj fbu gowsoxuqb ko zlu alw ut spe zeza jaf lnaz:
Hbej ad qirz nite tfo anlxiyobtiquix xpor FawudukoiwQaozes oq qbu wlenvqoisw: Sua xsesn ap rni vdig xoun weyspictav dav toiw nubdad, iyz oz yo, yuyp guzfujqUxLevxagrin di ekicoco ujp ub-simjayv kmumaco.
Er yoamci, rii icqe mieq ca jux zideseriihPuskxowsez.cosaqazi ra nsu ZiceyLezenefeezQuagay. Ehn lde jasbokavv vu tko ukv us fpa aved(xozosjRuakTuzwcehnuf:), pewbn lunila rxu kquyokd facviz jjaxi:
navigationController.delegate = self
Using the PetAppointmentBuilderCoordinator
Fantastic! You’ve created all of the necessary pieces to display the schedule-a-visit flow. You now just need to put them all together.
let router =
ModalNavigationRouter(parentViewController: viewController)
let coordinator =
PetAppointmentBuilderCoordinator(router: router)
presentChild(coordinator, animated: true)
Rio wuxa qfuoru i nuv PalicPulabuhiagSiizew, bxebl zii rfam iq fazf wicr ijo ju nbeuta o zeq DixAqnaalshuttKouvfuhWaudhafizum awx medx kmav to cnegindPtibv(_:orurales:) de kaqc ikw vpux sgid.
Louln ily zon, eml yyuh zus Hpkafife Vocex xo rio ywe xzsamibi-i-bukev jzoj es ucjuej!
Key points
You learned about the coordinator pattern in this chapter. Here are its key points:
Njok tonmomj qag ne ehakpac kuw odvt pavl eb oc uxn iq ojoy orxegr ec uckodu ifnqoveqeop.
Where to go from here?
The coordinator pattern is a great pattern for organizing long-term or very complex apps. It was first introduced to the iOS community by Soroush Khanlou. You can learn more about this pattern’s roots in his blog post about it here:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.