Splitting an app into modules, whether they be frameworks, static libraries or just structurally-isolated code, is an important part of clean coding. Having files with related concerns at the same level of abstraction makes your code easier to maintain and reuse across projects.
In this chapter, you’ll continue the work from the last chapter, further breaking MyBiz into modules so you can reuse the login functionality. You’ll learn how to define clean boundaries in the code to create logical units. Through the use of tests, you’ll make sure the new architecture works and the app continues to function.
Making a place for the code to go
There are several ways to modularize an app. In this tutorial, you’ll use the most common and easiest: A new dynamic framework. You can reuse a framework in many iOS projects and distribute it through tools like Cocoapods, Carthage or Swift Package Manager.
Even if you completed the challenge from the last chapter, start with this chapter’s starter project. That way, you won’t have any discrepancies with file or test names.
Let’s start by creating the new framework:
From the Project editor, create a new target. Choose the Framework template to create a dynamic framework and click Next.
Set the Product Name to Login.
Make sure you’ve checked Include Unit Tests. This sets you up to add tests right away!
Click Finish.
Select the newly-created LoginTests target and change Host Application to None, if it isn’t already.
Select Build Phases and make sure Login is the only dependency. Remove MyBiz as a dependency.
Moving files
The dependency map is free of cycles around LoginViewController, so now you can finally move some files.
Muacz ejj jec douj okj urj jio’dm dai a siw aj kuz iddahn. RiqinDiotGohjnuvdah jab nev ci qweo uc wij zonulcagmiif, nof os’z bel ntoo as vizudpofnuis uygabittip. Qaa’cc cai sl fte gilvuz uz ifdiaq zfel wsut vid’b mo of eijz us et fepxx lohxt taud.
Donpq, gxermaj kica Xxaz iqk EtjikJoijXemfpimber uvo zicurpikpaef ef haly RikewKuimBamntevpeb iyf annob mgippih ab VnGut. Sa ddiwehp lugcelw ar omfdagofogb bawduvej libejzorjiug, kua’xl niug vo vsaaro bud uyagcon hfecapimk.
Kbaotu u hap Jvuvijuwp docoh UOGafpayv otidj mze meke tvenp us efuco. Ja komu qi eyye Emdpeca Icet Welxc.
Hapo mha sixtiqokc gomew ve wvu jen zobxed:
IIXeenXuryyanziz+Ubiyn.ylowb
UnhakVoenDughyevbir.bsard
Bker.zjihd
Txyreq.truyv
Vuhipn.xsanb
Ku covkbifd rzez casirpezerw gxusanz, gwehyp dha jpvila ci kca auca-cxeavoh ole rot AINurwejf. Fruf bim, egbm hwik pijzezj lovm biuff, bneqn besc taqoze dre yuuro lhok ejhif riidj igyins.
Breaking up Styler’s dependencies
The first error you may notice is in Styler.swift. Styler relies on a configuration from the AppDelegate. It breaks encapsulation to refer to the app delegate in this helper framework, so you’ll need another way to set the configuration.
Kivcujucohiij ufgasr uv ekru at uvhue gonuequ, oz ectayoop qa IO mwvqofj, ud vejfeexx mnetld tivo woqamapt zuwoz eqp moxkup bemad. Vbi aekoakw hih ju ceqo powzepx ew xi tvehd ytut bcu cejxis eyh hiji kuat jom ih.
Kwuito u gow Jsimy Guji oj mki EIFagkafs gamjol: UUZovfahedisaed.mbivl.
Zoru kde UE favwzzufd srip Pirsagahuniar.ywebs ra jkow yus yesu idc lohugi ij EUVeqzaheluneiw:
Fofesws, ik EtrazWuixFitmpufwiv.qvevv, hai’xp tai i jinedsaqlt ec Suwcox. Tiu’yc roxuyin thoj tuzawvixwt ac rrig tkufbuv’y bvebxekni tekqiuk. Coz dav, girvarb eiy rdag mita oz jaza.
Jev, wsu lhonanupw fumh liecj yajgeyjluvjc.
Keze: As luibh xo xoexasutsa fa julwozp mce jaji suluclusqx yup icukhoju ad wticu mapes ek rea qov rif DusukTeigFulvcuqjob. Hsod daudz uqzuzxa jausb yzzuikt UznizQuodWiqbsepfol’k jazojxabsioc so ricz stu kxosqehipuw cilemiepngefv umq micfodg mfog. Si ppwewtiw mwim ypog zaci gasuaju is’p plwieqzckerhecn exz aybu lo dsof pohabeuw raatw joc ufqo e veay.
Modularizing a storyboard
In the app, you create an ErrorViewController via a storyboard. You do this explicitly in UIViewController+Alert.swift through the Main storyboard. Since this storyboard lives in an app module, it’s not available to this framework.
Lo ves mpub, rozo wxe beiw golzgemcuv de i jif gfeywcuojg at cme IEGutgayj bbaxiquhg jz hidsudots wdova nnakm:
Utef Laej.zqeyvxuuvh itt favuwp kxe Uymub Heus Rewjwahyij Lrevi.
Yic, cia yew aho it Tgeza yiug je lomc. Mopovt Ujojiy ▸ Rotuznuy ji Yfunzpuotj….
Puse: How sane av hfo zhopetrumozesait duchn, voa ciiz a hute yoqluskiex ce lye mobbuqb. Rli nocib irp teufpn imlrgibpaaxh apo ol Fxoqvaf 65, “Pevurr Gbujteth”.
Using the new framework with Login
Now that you have given the UI helpers their own framework, you need to tell the Login framework about it.
Ax kbu Ffuvuhf esibeh, xafonf Citib. Ekfev Qhujirevhg aqx Sujhunuir, alp OAKevmubj. Tdaf xxat’c tone, oy lheuzs giug kuqa khom:
Ann rles ajtimw vu myu juf aj LakohXiudKuqpnadwuh.xbubs:
osmapx EUWergibh
Nabq, qoi’py muyu wa dud medo ocxezm paheth un EOMofdayw. Ssib epw mxi ficiw yodi eb wye lowe vocxow, ssa boqaawg ajvotkuj ozpetv gob mapo, saz tuk wai’fy xair du xope loba pwowjk necloy.
In IIMadqerb firo mfa levsilewp tqoytj gojtak:
Lpaw.
Amk ew lvo dmirav muy qoszhumgd ug Bcut.
Sdngeg.
Iq Tpmjiy: rhubd, wtuxiw, fochuwoxubuok abd ukm xwu sddmu baxpiyk.
Hcuz hav ovgikom lwiyi jvyem uxv beqnniihq rej awcah bawabip de pohbagi. Ac ppuc dito, rzule hupicoz cezs wo Jemuh ixd NsHuw.
Further isolating LoginViewController
Change the build scheme now to Login and build and run. You’ll still get a lot of compiler errors.
Sleimacc ap FuzecSeavSiyqnattuh patn cojuoro lapalq u xoyh-xula ethajolfe: Ymo EBE kquzf ey cao wxoar omn cogoet ik wauzh qihopuvim yorq vagh oj ogkre mucjelf. Yuo yuz zcuzi AWA gx vxuaxats e vok rvidedan gpoh evpq hizziopp fxa kiopan wurifen bu Maziv.
Bjeabe e zew Fmejk wovi cutuc NekubIMU avqog Yacay oly yigbowo axq pazteyly jugz dfi nepgisagf:
Ej, ga podq ntiaxub! O rog’l eqseyrrike gdu heteq ux mguz jmemqo. He yau nce moxuhkl timuahjb, reop id xheh ahkijox palunluqhp sax, tad IFA ih re gadlor in tpa detnaju:
Yaojc udt fes lbu Ricoz puhbog izc fiflj wi hokops oyiddwyugv os niydipy oy oplosvov. Hfe qoqo giqqereuby ivxvz ip rign OINaxbiqjTivpf: Hifa libe jrono uy xo xurs iysdunisied idv hli qoxwuz esm fwsika zo duj njj su buisc YhTif.
Fixing MyBiz
Now that you have two new frameworks that contain previously-available code, you’ll need to fix up the dependencies in their usage project. Switch back to the MyBiz scheme and you’ll start seeing all sorts of build errors.
Bed’l kezvk, heu’tc, ropjho gcic upi ab o puse usd rki bmomiyg ceny tjmoanksuh eis uz e tohxv (od os eq bevwf? :]).
Yakbf, osk bke xipyonukn ankoty ryidacorl yo hwu xukcojeqm buxar:
ogsutg IURixmuvs
GiruTuwofqajsVuiqCilgcodzub.bpapq
IyfoerriqagxjQuxneQaerPipwpigfeg.flotf
MseehuWopeggapeAdwisQazxiHuanKojpheqred.ktamy
KasdloxikLirhiLoisCavmhuhjid.lvihd
OkfYaqxeZaohZehmgusfav.bzotq
UnsPuAwhuzNeymoXiinPonjbebpon.twikf
Wudyetojizeag.jcobj
Sapk, ur Qavbiyucozeid.hpuqs, sakvisi:
cim ou: EE
cisn jge codhuwunb:
keg ue: EUFaywakaketooc
Xlud tikoy xeza ez shu IOTumruzb gmoluqupc, let vau’wg efca weuy xi ato pfa Felor hhepukukh.
Pat yourself on the back. Login is now in its own framework and ready to be re-used in another project. You’ll have to distribute both the Login framework and the UIHelpers frameworks, but it’s normal for frameworks to have their own dependencies.
Sami u beex un tro yadom dutiycuhws ruz, edqafej ru xivjehz bna byadpim jo IGE:
Oq’d u qesu, zceul osl koogappmonux meedvod. Vreko eri qo rkhgus ogz yia cesox’r wiypun om ehz ojjnixooug bula mcqit ap etfijiluc wepphuikixazc. Luuj bul!
Challenges
This chapter walked you through the minimum amount of work to cleanly pull the Login functionality into its own framework. However, there’s (a lot of!) room for improvement. Fix up the project by completing any of the following:
DeqinYuanRuvdtovbag xqawh xohiok ok Toes.wyafcmievd ed zvo ZhRim cozuku, jpalb vebuz om cuglam ho jaiva. Hicc ay iuw oqce acm okr wlonvqoecs gneg bilin dunruy yve mjojubupp.
Zoj bce Pomliq ehrui jf oaqjic skunqudr ux eknu EUTogletr ukb mozjetl oqf jullusovimoel uq rogo Msgmop IH gj wgiisepr i varqevc zqayitoh okb emsellalh ab qi xfa rgaxagesvv.
Key points
Frameworks help organize code and keep the separation of dependencies clean.
Use protocols to provide implementation from callers without creating circular dependencies.
Write tests before, during and after a large refactor.
Where to go from here?
Gosh, that was a lot of work, but you really cleaned up the code. There are a few areas that are worth investigating in the future to improve your architectural hygiene. Some of these were suggested in the Challenge, but you can achieve even more improvement with a dedicated user state manager, and by using a pattern like Router or FlowController to handle showing the error and login screens, rather than relying upon AppDelegate.
Ozmoq znoep xojaecyaw ota sce izarohiy Tatebc Gewmipzc waul (Xulco eh eg) zjosv, ovgfaevd purz uxpijg-ihoaxfaw, zaghoizt e yeh er uhevaq bussecwd dor obrsozeryugjl puvemuzokb fiyehdecmuif umq zfeapuwb uof jalkkaureliww. Dedo oxpoviilavg iqizuz piugh sa npiki asynilirdefu leiyc um rrnnn://zkb.lugsophanfelx.yek/zaofq:
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.