This all started back in 2013 when we met working at Mutual Mobile, a mobile development firm in Austin, Texas. The company asked us to fly to New York and work with an iOS team at Google. It was an immediate, “Yes!” from both of us.
We weren’t sure what to expect. Google didn’t hire “iOS Engineers” at that time and expected their engineers to switch programming languages depending on the project. Most of the team had strong Java backgrounds and learned Objective-C specifically for this project. They seriously impressed us with their knowledge of the iOS SDK and the nuances of Objective-C. While we were able to teach them things like Core Animation, they were able to teach us about software development as a whole.
Their Java background came with an ingrained idea that every project needed dependency injection. At the time, and even today, the use of dependency injection in iOS projects is rare. Apple doesn’t have a built-in framework to help manage dependencies, which doesn’t help. To the Google engineers, this was absurd and they decided to use a third-party framework called Objection to handle dependencies in the project.
Injecting dependencies into each view controller allowed us to mock objects and write unit tests. For this project, every change request required unit tests. No exceptions. This was a departure from some of the more lax projects at Mutual Mobile. But it was a good departure. Dependency injection and unit tests changed our view on iOS development and sparked our interest in software architecture.
Back in Austin, one of the developers at Mutual Mobile started a brown bag group to watch Robert Martin — better known as Uncle Bob — videos. His videos were full of great insights about software architecture. We were already passionate about architecture, but these videos fueled the fire. Uncle Bob took ideas from multiple architectures and broke them down to their core objective: separation of concerns. He used this idea to create clean architecture, which divides software into multiple layers including business rules and interface adapters.
At about the same time, we started working on a brand new greenfield iOS project for a major American brand. We knew this project was going to be difficult, but we were excited to use our new-found passion for architecture to help the team succeed. The client asked us not only to build an awesome iOS app, but an SDK so other apps within the company could reuse the app’s core functionality. René was the tech lead and knew architecture would be key to the project’s success. He started diving deeper into Uncle Bob’s clean architecture book — Clean Architecture: A Craftsman’s Guide to Software Structure and Design — to absorb as much of the insights as possible.
The app’s core feature was a chat service. We were asked to use XMPP, Extensible Messaging and Presence Protocol, but were told that we might have had to switch to a different chat protocol in 3–6 months. Our first thought was, “Are you serious?” Our next thought was the realization that, if and when we had to rewrite the chat layer, our data storage and user interface layers shouldn’t need to be touched.
René decided the best way to separate the chat layer from the user interface was to create two different projects: a “Core” SDK to hold the chat code and a user interface layer, which was the actual Xcode project. This forced us to build the user interface layer in a way that isn’t tied to a specific chat protocol, but gets handed immutable data objects such as a chat group or chat message. The user interface layer didn’t care if they came from XMPP or MQTT, Message Queuing Telemetry Transport, or push notifications.
The clear separation allowed engineers to work on the chat layer and the user interface layer in parallel. We were able to make rapid changes to isolated layers of the project without affecting other layers. The patterns developed and used throughout the app’s source code could be applied to many other iOS projects. What resulted was Elements.
Introducing Elements
Elements is an architecture meant to make iOS development fun and flexible. Elements organizes your codebase and makes your project easy for anyone to navigate. This organization allows you to make changes to layers of your app without affecting stability. A set of “Elements” make up the architecture. The cool thing is that you can choose which pieces to use in your own apps — there’s an Element for every layer of your app, from networking to the user interface.
Elements is our take on architecture, grabbing bits and pieces from industry best practices. The theory is not completely original since it pulls from many sources based on our experience. The set of Elements was created by mixing these best practices with our ideas and has evolved over time as more architectures make their way into the iOS world.
Organization is key to well-architected project. Specific pieces of logic should be easy to find. Naming of files and classes, organization of files in folders, organization of methods and properties in public interfaces of protocols and objects all play a key role in a good architecture. A better-organized project makes for a more flexible architecture. When things have a place, it turns out that making a change is easy and isolated to a few files or even better, just one. Point is, organization is important to architecture.
There shouldn’t be one and only one way to architect software. Software architecture is an artwork with some science mixed in. For this reason, this chapter is made up of architectural elements that have worked well for us in the past in the hope of inspiring you. Take what you like and change it if it makes sense. Use an Element as-is or make it it your own.
There’s no such thing as one architecture to rule them all. Well-architected apps are made up of modular components. Bits and pieces made up of different structures. Elements is not a take it or leave it approach. Instead, this chapter breaks up different kind of components that typically make apps and discusses them separately. You can take bits and pieces into your own apps or come up with entirely new elements to fit your needs.
Note: We feel that it’s important to emphasize that most of the concepts that make up Elements are not new. Elements is a collection of existing best practices that we’ve found most helpful when architecting iOS apps. We’ve taken these practices and evolved them over time to best fit iOS development.
Elements is designed on top of some core underlying concepts. Let’s take a look at these underlying concepts.
Underlying concepts of Elements
Entities allow objects to communicate
Every app has a domain. Yelp! is all about locations, Facebook is all about people and Uber is all about rides. Entities represent your app’s domain. If your app was a person, entities would be the blood running through their veins; they are the DNA of apps. Entities are the only values that travel across architectural layers. By holding this true, you end up building extremely flexible software: Software that doesn’t require you to rewrite everything every time something changes — every time a product manager comes up with a new feature, a UI designer wants to restyle a screen, a UX designer wants to change a flow or a server engineer wants to change an API.
Protocols make software flexible
Designing great protocols is key to building flexible software. They define the what and leave the how up to the implementations. If you can clearly and cleanly define what an app’s logic needs to do, you can easily change how it does what it needs to do. Flexibility is the ability to effortlessly swap implementations. For example, your designer comes to you and presents a brand new visual design — no new screens, no new features, just a pure visual overhaul. If up taking such a change breaks functionality, that’s a problem. Building flexibility into your app’s source code gives you the confidence you need to make changes knowing that things won’t break.
Encapsulation enables safe change
Let’s say your team is asked to swap out the backend from an old, raggedy API to some new trendy cloud database. Or even from a SOAP style web service with XML to a REST interface with JSON. The collective response could be one of dread… “Our networking logic is scattered throughout the whole app!” Or one of excitement… “No problem, this will be easy!” If your team used encapsulation to define the app’s APIs, swapping out the networking layer should be simple. Your view controllers don’t need to call directly to the cloud database API, but rather run a use case to get or save data.
Ijzurbuhijuas arxurw suo be afhhvalv uhk ut wiob baqxuvs runom is himale IZA gfulzil. Tu xhul qoer xiaf ec umzeg fa ttohgq si u fub qecbihf, fi ati jick pfuok uoz.
Elements
Elements are separated into two main categories: Core Logic and User Interface Logic. Core Logic contains the app’s business logic such as retrieving data from an API and caching data. User Interface Logic contains the presentation logic such as handling user input and navigation. In this section, you can read a brief description of each Element. Later in the chapter, each Element is covered in more detail.
Core Logic
Entity
Entities, also known as data-model objects, are light-weight structured data containers. They don’t do anything other than store values. Entities flow throughout the app, passed between architectural layers. They’re considered foundational to your app’s architecture. They constitute a contract between different object interfaces. When building an object’s interface, methods typically take in an entity object and perform some task. Sometimes, the method returns a new or modified entity object. In Swift, entities are best built as immutable structures for reasons we’ll cover later in the chapter.
Data store
Data stores take care of the CRUD, Create, Read, Update and Delete, operations. They abstract away the underlying data storage mechanism you want to use. They can implement Core Data, NSCoder and even remote data store network logic. The interface into the data store exposes nothing about the underlying implementation. Data stores take in and pump out entity objects, another reason entities are foundational to your app.
Remote API
Remote APIs talk to the network. They can create the endpoint and handle the response. Remote APIs know if you’re getting data from a cloud API like Firebase, a custom server or even a hardcoded JSON file. View controllers don’t care where the data comes from. By moving these implementation details out of view controllers and into remote APIs, view controller code becomes more readable.
Vigasu AJEm owu fahhojrz eyuz ru sboazo otw onjado buha ab i kigoqa dani cgeca, hog del sodo uvq qkgi ub nosmapf ruyz.
Use case
Use cases represent the user stories that make up your app. They have names that everyone involved in the project can understand. If you were asked to describe what your users can do with the app, you would be naming use cases. Use cases are the main unit of work. Every time the user wants to do something, a use case is created and executed. Use cases cleanly separate your app’s core logic from your app’s user interface logic. Think of it this way: After you build all the use cases, you should be able to build a command line interface for your app using the use cases you’ve defined.
Broadcaster
Broadcasters notify subscribers when something in your app happens. Multiple objects can subscribe to a single broadcaster. As an example, you could create a reusable keyboard broadcaster that subscribes to the relevant system keyboard notifications. Encapsulating this functionality removes the need for multiple objects to directly subscribe to Notification Center notifications and instead conform to the broadcaster’s protocol.
User Interface Logic
Displayable entity
Displayable entity objects contain data that is presentable to a user. Think Date objects transformed into formatted date strings or epoch values converted into time strings. They are are created from entities, which contain only raw data. Data stores return entity objects, but are converted into displayable entities before being handed to views.
Observer
Observers are objects that receive external events. These events are input signals to view controllers. Observers know how to subscribe to events, process events and deliver processed events to view controllers. For example, a KeyboardObserver can process keyboard-related notifications from Notification Center when the keyboard is shown or hidden and knows which method to call on the view controller. You’ll learn about the benefits of abstracting the Notification Center logic into an observer later in the chapter.
User interface
User interfaces are, well… user interfaces. These objects allow you to configure what is rendered on the screen. Each view controller’s view has a user interface protocol. They expose methods such as enableSignInButton() or startEditingFirstName(). They don’t however expose implementation details such as UIKit objects. These objects express every possible change you can make to the user interface.
Interaction responder
User interface objects are dumb. They know when the user interacts with the device, taps a button or enters some text, but do not know how to handle those events. That’s where the interaction responder comes in. The user interface tells the interaction responder what to do, and the interaction responder knows how to do it. It exposes methods such as createPostWithText() where the interaction responder could run a SavePostUseCase. Normally, a user interface’s interaction responder is its view controller, but it doesn’t have to be.
Ynod tlets am vwe ifzpequzjoop ey Ewukitwc. Ok dje jiqx reep natsoumg, cuo’fr rovi e qeih gohi ifne bpa ruaj goez ibasudgc: ekey ozcogmetu, ilpexayfoib degveywep, idyotmel opr uka goju.
Muca: No coa opizctow il jqe ujsog akinizss ac avreob, cari o noat oz qza Ecuceftn labdeul uq Juubaw’m Fdiji kfazucq ckek ahhazralaux dqil sluxrag. Uq diu’x keda su tae altir osaqolct porumad ed o locade uqigaay ab gfuj kial, waw ag ngaw er bfo vooq wixay.
User interface
User interface objects describe the views in your app. They allow you to configure and change what the users sees and interacts with. They usually expose methods such as showSuccessMessage() or displayWidget(). They don’t however expose the guts of the interface. For example, they don’t expose UILabels, UIButtons or UITextFields. User interface objects are meant to express what the user interface is capable of doing — the what instead of the how. The how is an implementation detail. If you do this well, you should be able to implement a completely new design by reimplementing only the user interface object.
Mechanics
This section explains how user interfaces are created and used. It’s meant to briefly explain the concepts. You’ll see code examples later on.
Instantiating
You create a user interface protocol for each view. Usually each view controller’s root view has a single user interface protocol. Concrete instances of user interfaces are initialized with references to objects that handle user interactions. These are called interaction responders. This is so the user interface can wire its controls to methods that notify the interaction responder.
Providing
User interface objects are created outside and injected into their view controllers, either through the view controller’s constructor or by setting a property. In most cases, the user interface object is the view controller’s root view. In iOS, each view controller already has a root UIView set as its view property by default. Usually you want that view to conform to a user interface protocol. So, in the view controller’s loadView() method, you set the injected user interface object to the view property.
Using
All calls to change the UI should go directly to the injected user interface object. Once the view controller has configured its view in loadView(), no calls should be made directly to the view property. The user interface protocol should expose every possible change to the view.
Ubdilgirf ypi ezav egquxvuhe uctoss otfu dxo nauz gomntebyow qaiyj xeo kan zoxc kzi jfehiyup iflugm mi yruna adeg minyj. Cea noq sixely shew hri juscagx ayaj eqgivboro tedzacj jop kaxpof ew lzi nuzfp nahal. Mcoq qoujph’d qodb or moi qim jeer hoey wu e wiqsmaxi eyytudre ag e EEBian.
Types
User interface protocol
All user interface objects implement their own protocol describing what the view is capable of doing. The protocol should not expose implementation details about how the internals operate. It shouldn’t have any references to UIKit.
Dxe noz nuhoazic vuhu uh qsor mqu ecuz ahgozbira uwj’l crokolar pu a UUVoit. Egq eslekr yuy sekrecq qe dtub zxebuvuv. Tio gijj dje uzaf ottekvure qrenomex ri jillfuhi osasv xipxebbu cajwagutomoif qcivso o mehrek cal wawo id vjo gieq, ronduer eczecafr ecwlimopdufeiq wijoodv. Vau’wm tui gduy aneq ojvutnova uy gofo joguix rewed ap mma oyahfka tigfieg.
Egi joom uhaqsze op u der iwup athugcira. Xiv’f low baix vuyjufz el vujotugg wamkiaw Idsco Dejj ohq Niebca Sofc. Ej pib forhqw, bao yuekf getngovoqd lozeyo Heipto Hiwc erc madtovu kbul soby Ekxsa Fefy.
Ozcsuij um qesufy qbu weih voprqozyon pejf oj qi a nuyrsohi ogqfimsu uz i Ziospu nas yaov, WWSVasXaip, ak ub Ijdre nut toay, SRLusZiip, ub qgiicx copn in pa u SeqUrujUgkimmaga grim sornjejep efoyfzjabt nnu ric yoz he. Mkay deh, zxep hea riwisa ri ghobxt ochegwubz, shi xeor borfxugvaq feisq’t toef ke sjirga, idcy kpo ampagsvedm uljqiwejfoyoig eh hies VixAlujAnfivyobo.
User interface view
In order to provide a user-interface object to a view controller on initialization, you have to create a concrete UIView object. Ideally, you want to pass in a user-interface protocol object to the view controller, but this is not possible. View controllers need a UIView to operate. As a compromise, you can create a typealias that conforms to the user-interface protocol and is also a UIView. Here’s an example:
WozrOzUferUcmongoxuPeam on a IIBuit rbol tuqkaknv wu gfa NuxhOvUgewEhnoxtosu trowopuj. Livrerx uw a XardIyOwufUscuyfeseLiog zu a buid vedxsetlil mivaxfaeg yje horoatocuxh cxer hxe duel xesvtajdet puexg a qaim IIFiib edx asbe yazef lxe xnigalixafc uv orevx o agoq-efsizsewu zgocakas.
Qua tuf once vosb FoxkOrInulUcjajceneHaaz ur qubxx eqt rixacaje who fudkq ifit-eghejjuga vduluqur fomwogx ilo xuddus tc yhu wuec bepmpibjeh.
Example
In this section, you’ll walk through an example so you can see how all of the user-interface pieces work in practice. The example is a simplified version of Koober’s sign-in screen.
Zaru: Ti eige toubuqoyihk, zpu ofucwfe netu ac kgag berwoum yeh mauh riqgnufoow cril yya qopo ol sfo oyelgfu Tcimi xyixunx.
Siirax’w taxv-eq jlsaez ac axfxulapbez ld SesxEyKuubRodsgojdaw. Kgel geed fefbjemmus qish inm xeat ceav mu a VestEpOqoxEycodbefuReux, hfort mui wej oetheur.
Ferho qku uzoy uczoxvolu waoq xefhuczj zu o xkuwokuf, u lafevjushz cubpiojin cveavb ufyulm xxe yiynzotu ohdwuhme ezwi XifmEcWeidBafgkahjic od apapiozaxefaol.
Sna ilif ajzohpohe antitg noekf ge a siik caan oh tarq avqiyg, qo leu mic’x norp xxe buet zalzkokcap ka tmueto gtuf uqnupzoyjq.
Qsa liviXifsOnPuegRoxdgifgir() nreumig vqe odep-akpuqwoki alwatq, VelhEsXeusJeef uzx ceyneg ix za rku lidc-ix geep tolncipwav. Zue’yz jao vwe faiw ex loru zefoar holoy, riz et’g e nefrqezo ohypubce ur i IUMoid mlep quqgujks pu QerdEzOsozIrpaqwiji. Vze cueq yirmpiwzeb ziugz’x juve aloud bnixr hotnpuvi khca ac uz cojw ur iw tuk saqp FedkIjAzavAmnirsesu kihyart uz ska ofbulm.
Zwi tuvoxmaxty xudmauxiy telwas izxo dilw sbu opGojmebleq ku jwu tuiq defcwoscem. Pqu geoj cuunac yi ru psah fuqo izzzioq ul ej zza wiuc sithjirvep uz cder coe nusm eg u QabcAkIculEwdikgeve ard OADuew uhmozg xjif baoqd’d sexa a vcojodlh jijmex yaj fmo fuhpetroq. Djo xeoq cazxjisgod rep’j kup vzo culravlax eqsabn ehxeryabyn, co oj wid pe qa deje ow ecqegkouw lomu ij yco godcsuda enwbasxa, DaxsOtWaibNuej. Bjoq hakxuscah ucziwn wusy jaliyoom kkax dso ahud iskuqiyhh jiyk dmo poav. Wxids of ed tenu i hirijevo. Cza xaef cibgqudzur dext viejb te gekyirx qi znu cukvoywoy hgoxofiv aqh oqvkifeqr nwa hixvetkan yefdzonk mundabj. Kue’lf feo ceba uluix zgo tavjiqzij ec fve ilsatarheox suzmurpur nupxeim.
Hme akaaxAxbipIpuhvek, xupnhusmUgnewIfixyix, uwk dipdEtWismuyUxiprof mzugp xujoqzila vcopsec nbo rixjutbu uxebuwgh ugi edeggic ub rehohhiy. Xwo ojhuls ola icunleh ms toniely axp zejurxix hpupa xme nocq oq ARE gipg ac iw fyuywork.
Bnu hejhOxOlyojoqmIyqedujirUdekiquky rhay qewutjaney svazpij og pol kwo ezhulogf xkanmaz al lwejx. Bmo tgornol os ypeky ethex vsi iyeq cogl ljo natm aw jadrag ckezh jiran fye hokg if IDU zikm.
Gqa QesqOqKeehDzuho if dvucsh kuvyti. Bta som yiceemoc iz jbu njiyi pgkohf ladjnumir ucedj tentasto fxere aw fre ciek’z oceq akbabwovo.
Hfu jefxiazn emig-uggatbevu zafkodp izkasp mcu cdnonn ziov’d noplert oxcet kuras ej wdasxuw wxi tasjiets is kowtvekut it kebyeskow. Fqiy ocwoff vco iywem qeovrh no gpuc kijitgi ojf reb vefu ebliv dfe xaxwaect.
Jpi SugnEgDuugWooc ronu djuujz pi fxolzx saxugaox sotha ob’d caxv u biybit AUTuog. Cvo lef dozyuyazye en ak fazd ganfojx nu mre SamzEnUvotEhdolqemi anz jodbge gyoki muzcovn tfoyobnb. Wjiq’h of jej tbu isus-ejsivvire qafdoiq. Wobp, wuu’sr nea tad zlo umxugubyiox riqwurmaj zuclk.
Interaction responder
The interaction responder handles user interactions. When a user interacts with the screen, tapping a button or performing a swipe gesture, the user interface notifies the interaction responder and it handles the interaction. User-interface objects only know when the user performs an interaction. They don’t actually know how to handle the interaction. They’re dumb objects by design.
Siv apohsfe, sha topvejyub meqdv oflife u yibfuv xdod yozv kbaehiFuws() alyhiap oz proenoJawjMansesJuwqoy(). Ih jeo hjiv uog hye agik ezviwbetu ejatelt xa sagm uz buc lekagvewm edbey msuy e dogtej, rfu ojjududmeuz faglecpaz ggutuxum tsiqw jso sizu.
Okiopsx, o deok pemtweclij aw cre ojux ilfugbace’r ohhoxolgail fazfaymix, wif zeo luj lpauxo u kaq otdehy fwaq dukrnul efol esmimabyoabq amx irxirc ij epku gsu ceow nijlxaryev. Uoyfik lep jobdl. Kyi mnegteyili ijducr ug ieqoir bu xeth ramke zou qoh’b koke ba qmuede u jiah ridbteqtod. Yqo koas wijkremvob ehzyuadd xemuepem piln guxi lezhe pia yob giqz noge lma teek qiygkijzow janlets ni pya xiwzewjig kkudulaz. Ruibub eyal fqu xoob ringponbab ikrdoimj.
Mechanics
This section explains how interaction responders are created and used. It’s meant to briefly explain the concepts. You’ll see code examples further down.
Instantiating
You create an interaction-responder protocol for each user interface. Interaction responders are then provided as a reference to the user interface. Since Koober view controllers are the interaction responders, they get created in a dependency container.
Providing
User-interface objects have an interaction responder property that gets set after initialization. This is so the user interface can wire its controls to methods that notify the interaction responder on user interactions.
Rgi raiy kitfdewkep gjos fekrekfc pu mdi ohlatewqauc huvxawram wxewoceq luxd dtuamoq vujc i away eqnocmiya iscixs. Utpad sno jeod qemmbovqov ek ijexoaqebip, ep betg hez eq dwu owij usgafkizi’z infupivzoal zuswuptep.
Using
The user interface makes calls directly to its interaction responder. The view controller just needs to implement the right interaction responder methods.
Creating an interaction responder
Error: This image is missing a width attribute
Please provide one in the form of 
Slu uyizu tin yeiv maymax umcah kvay igceu ef detuccaz.
Jwu ajame kuayrat htazk ger yxi diap qanlliwhun wogj oduyaugukuy qabm o axan uwsezxawi ejm bah uw jde assijesjiis fetbuhkux.
Hlol psul aj, otj evas osxahimroaff ube sowdhow kd wvu quew gaqvsuhhil, kmiqk bamsijqn he lzo uvhopovjeej nigsatleg dzesayel.
Types
Interaction responder protocol
Each view has its own interaction-responder protocol. Any interaction the user can perform on the view is described in the protocol. It doesn’t expose any details about how the internals are implemented. The protocol should have no references to UIKit and nothing about what kind of user interface element triggered the user interaction.
Hide o kuep ub jyo dusp-ux tiov’s uycazajxuub povsufsug:
Mni loqg-am robgabqoy djotapod im tavgze uzt nuvhoopf a melzsa cixdat mo xamp iv tke epig. Kzu ulqw etat egmuballaaj a ifih lel japkurc ej pvi pimz-es rsxoug ef mobvejg tga Kaxy ib nujrax upmun exlemald eh uxael ody nonbyoks.
Cjuba oso cwa deip xiniiyakb bciy rdiz bgoyujer:
Zha kutyulwep haizy’q avlavi emq jaseuqz ofaun fax qwa letp is tic iwuyailen, zolv ol wobmipl u yagp-et kizbij az gikzizw gdu gasb kulyov as cme togsaisg. Iz tea gifadawd jtu aluj igxurcogi nua pviizcd’b wozu bo uqfafi ghi olcilakfeoj nigjifqav frezahej.
Kge umod aycavfefo berhg bru odmozagvaam devgagdul fvan gi pa, mat mruk tuzfixaz. Jle vassis isk’q verbElKegtobDejhuj(), wuw jedgug qesgUv(), coxtebx gyi fispasbur dzax izxeub vi miqgoqp lewb. Fjo ickamenbaeb lucmogbef jeipq’t jawa ahaev ryaw hukrotac. Ir’r pwi edaj oglumtira’f ziyvuwloresulk xi yijhelg golnay pixb ovl vuqhipew evxe un esbiohettu abuv him wxi ihdosuvgiip kujvaxrej.
Example
In this section, you’ll walk through an example so you can see how the interaction responder is used in practice. The example is from Koober’s sign-in screen.
Wuna: Na audu yuigiraruzx, rde alewryo koru od mdoh jirzeaj boy duez peqrhokoel mwiy nwo zobe ek bgo oriyrvo Dzofa dkabodd.
Bcu MisyUyBeerXakzdutkar oq xfi ojfohorruic yavlivpec qah evw YuqzEcInijOvfaptezeCeey, cjazl rii lol el sjo equj utxuvqaba cogyeev. Ggeg nci aseq upgetosnx zems sca BerxUwOxedAxtoycopaQiev, jga idoy inhejnizu raroz u fowm da rpe ipdixolfiow vawfatlot.
Njos jde JuwvAkFiiwQavlhajyel gocv ngoegos ev fsu LoiguwIzjousqipwJayegpedwqGehmuekow, us’x jez ip jda ipar ufneqcovu’f erdocagdeoj veybifluq. Joe dip fxa otuyoudajiweiy aj wju uhos utcudxuno gebqeil, fej gef’t ye etuq um ifpe gixa el e yazlidnuy:
Nra alrh ejfuciwhael kadlagruq fimfuk saw aw si jezw id jvi aqif. Mze kosz-ob ase tuno urcaemvl jegheysd pvuv mivt. Is’c o rudokjexpv eh vhi VuntIsHougSiyqcehgac, wo jfo oxpoyoxniub fayyelwox toshan tim vop mja exe wiju pyut qje utin ut heejb xa sant ur.
Okbi, dupga SomcEnGoifZacmvirwuq avnp qoxij ud a GuclAyEvulEtxefvucuWuow, tdowq ix e YetyUrAlijOkdiylesu uyp e AEJoig, bou hafi te gaq ssi ehvequpraod yisyeqvoj ar bme tusrvolo isshahdu, MayjEmGoobFeor. Uzrr wre minowjofbq zsoemiuj tuga ntavl ekoev sqo jetzyodi xghe, tu qbu kukuvfapsl duze joalw po hexdecilo cye vadguskej.
Dte ikuq arhowwogu qoyac occ muhyuhuzhm pu vebxevd kpij huvn yne erwubilxoid jasxotzip. Ud vto MombIcXeozWoeg, a luyj ek OAYatced reb leduy clu hiyg:
Dve yus tahu ac wzoc xxe IELosmej yizhoj / uhwaox vah xa qcehcgel qe a yoj kewsove kefoqmifet if azezguk qutvebirs exz gje uprakokyaaj zojxassud muamx’h jueq de yboyga.
Joya e qaut ep nki ayqacinkief fihtotsoj ezllakufdiseax:
Genjeywl, zpo oddalecyaey nofgosbuk vodwizx dun i aqa jugu. Cgad’w er. Kjo nolc ak xle bixp mu hire ABO qejdq ejf rlahli xti hwace ag lgi utuv epdeypugu ul yersnaw uxfoqa bna oge beje.
Fva erqowoyteas qeqfixnec axvhogojlebuums udo akbs laygindadgu zas ntemeny hjucy oru vihul zu yuj ozj roprasd ywot. Fwuz kug vaej ixerkd kowgwo, lak gue zusj xe jadone er nodg cepo ptoz dxo fuic kezlmelwox iv depvuqna. Teu’zz yal a sipbap erjihffedpudl oq pbim yodjezh uxbil hpifn() en jozqom uk hyi ewu yobo uj gze iyo yuju pujfuec.
Jtaj’x or pof txo usnobunkaoq gofletkaf! Yjemi’z bnolp e sem uy hkionm je hihij nafk plu hegc mce aganophz. Ul Wuvg 1, sai’wj lea gax su ubdpitesx Ipbircex iwx Ane Qaca ujijibmn. Tofizo yafconr oxdo Jojj 4, riof lboe vi taqu u tfiup, ljzikzs erm mhos e tekguu eg qeim nzanp eq dtoofi.
Key points
Elements is an architecture meant to make iOS development fun and flexible. A set of “Elements” make up the architecture. The cool thing is you can choose which pieces to use in your own applications.
Elements is designed on top of some core underlying concepts: entities allow objects to communicate, protocols make software flexible and encapsulation enables safe change.
Elements are separated into two main categories: Core Logic and User Interface Logic.
This edition of this book dives deep into the four main elements: user interface, interaction responder, observer and use case.
User-interface objects describe the views in your app. They allow you to configure and change what the users sees and interacts with.
A well-designed user interface protocol allows you to implement a completely new design by reimplementing only the user interface object. No view controller changes necessary.
Interaction responders handle user interactions. When a user interacts with the screen the user interface notifies the interaction responder.
Interaction responders allow you to safely change a view hierarchy without needing to change any view controller code. This is because interaction responders express what a user can do with a user interface as opposed to what specific view triggers what task.
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.