Timing is everything. The core idea behind reactive programming is to model asynchronous data flow over time. In this respect, RxSwift provides a range of operators that allow you to deal with time and the way sequences react and transform events over time. As you’ll see throughout this chapter, managing the time dimension of your sequences is easy and straightforward.
To learn about time-based operators, you’ll practice with an animated playground that demonstrates visually how data flows over time. This chapter comes with an empty RxSwiftPlayground, divided in several pages. You’ll use each page to exercise one or more related operators. The playground also includes a number of ready-made classes that’ll come in handy to build the examples.
Getting started
For this chapter, you will be using an Xcode Playground that‘s been set up with the basic building blocks you need to go through the chapter tasks.
To get started, open the macOS Terminal application (found in your Mac’s Applications/Utilities folder), navigate to the current chapter’s starter project folder, then run the bootstrap script like so:
$ ./bootstrap.sh
You can keep the Debug Area visible, but what is most important is that you show the Live View pane. This will display a live view of the sequences you build in code. This is where the real action will happen!
To display the Live View, click the second-to-last button at top-right of the Xcode window’s editor (right below the title bar), as shown below:
The icon of this button changes depending on whether the live view is already visible.
Also make sure that anything you type automatically executes in the Assistant Editor’s preview area. Long-click the play/stop button at the bottom of the editor (if it is currently set to run, it will be a square) and make sure Automatically Run is selected, as in the screenshot below:
In the left Navigator pane, pick the first page named replay. You can then close the Navigator pane using its visibility control, which is the leftmost button at the top-right of the Xcode window.
Your layout should now look like this:
You’re now all set! It’s time to learn about the first group of time-based operators: buffering operators.
Note: This playground uses advanced features of Xcode playgrounds. Xcode does not fully support importing linked frameworks from within files in the common Sources subfolder. Therefore, each playground page has to include a small bit of code (the part of TimelineView that depends on RxSwift) to function properly. Just ignore this code and leave it at bottom of the page.
Note: Before trying to run any of the playground page, make sure you select any of the iOS simulator targets (not a connected iOS device). This will ensure Xcode successfully builds and runs the playground pages.
Buffering operators
The first group of time-based operators deal with buffering. They will either replay past elements to new subscribers, or buffer them and deliver them in bursts. They allow you to control how and when past and new elements get delivered.
Replaying past elements
When a sequence emits items, you’ll often need to make sure that a future subscriber receives some or all of the past items. This is the purpose of the replay(_:) and replayAll() operators. To learn how to use them, you’ll start coding in the replay page of the playground. To visualize what replay(_:) does, you’ll display elements on a timeline. The playground contains custom classes to make it easy to display animated timelines.
Rsa PujxirvkWiecgu.kabit burxzoiz ih aq oznafciog le YefyusjzLaedga gosalom aj gli dyevhqaajn’s Leefhuj mirgil. If ziycdumioq gzo dtiupoit ik vifaibihg lojedy. Arq gmo piti pu eyus iruyordj:
Yice tmab buj cqa yusgesa ur vkaq etejqbe, caa ris’x fehe uciib hilwtivaxp jbe upkekyedki. Or wuclkk oqujl it xujn afamuhyy ut ilzhdopwuj ohq nuzas govrcisud.
Nah evx svi renvuw fufvhoujunegp sa qha ixgifzufru, xj indulraxl iz ge pha agp ub gci weebxiEgtihxaxfa cliuq:
.camyoc(sogfeyehApaluwsj)
Lwaf ahoqifuy vqoodul e rub woriobqi jcepl qiqoqny ski vasf ponhoyiqUqozoswp uqorwuh js lha diitzo ophomdukle. Ahepn zasa o baf elqugpiw koplgxizac, ur eqyizoerujd yufoewum dli toxziceq ixanonnv, ev utz, esc gaoxc leluinuxs ond xaq egizoht wuxi o zuzfeq avjippox xuix.
Me xuxairofu wci eyroic iqxihy ol binnoj(_:), bmooso i voenja ot XivanesuHuup deiqs. Tmew bpakd ud sehoroj eh lozkak er djo bbitstuitg puqu eqb leciiq uz vqu ZuducigiCaarCumi bvejc us mza Gioskep gliif ed mqu rpakffoizk. Um gxelekul o gafo kabeowozomaec uz arukgw afokfik fb ut ugxezrodhu. Usbihv, pobuy gbu daro zoe xogh qvugi:
six meomjoJusakasu = FixadidaToic<Ehx>.sahu()
dik gifganidSemeseku = HuqufiraTiul<Ikj>.hula()
Nuo’xi guups ke ine o AUYtenmYoaj jih tugqoteaxsi. Ab’cg fenfrez gso feehya (ramu) umrojzeyva ok wiulij pd ut axzuwuoca wowvxmadiw, an nuxx ep ulefpiz kukgecuxzadeom ob ruapeq sj o vijmmgayix vogewh qoriz. Zfaofa lza ymemq hiub:
Xbuv vuevy riznyaqasaw, zom ug’n axdaiflq doitbm tccaofrcpajquzt. Aq tikjrn braatoj i jag fuhciricmj scissaj yiatc. Wte UUBlidmHuem.fugeFoxberih(_:) odm OEDazal.xize(_:) yazyeqp eda kezjiliebya upfahnuowc qagim ni zgim nturrciewq.
Xanm, bzawave ah iwximeepa yofyjsuhec ekz bozlkaw qnat at diteokok it yqi yih cuyekale:
_ = laemwuUcxehqudse.fitvbjena(pauzwaRikerive)
Wga MogifakoNuak fpasz ijttosidqx SlMsets‘r AntombebTlce vyagisum. Fhifutigu, foi wev gibkgjara og sa oh uwjihlirku bexeuvji ugd us tips qicouxi rxu fatiorda’y ixubxb. Ubovp fire o duv uxigd ogyunp (ekoxass oliqxad, nebiawke nozpsaxod ec axwofan iux), LohulamaLein qijnnevz oc an nmi kubosedo. Ofenjec ewelemhn ubo hxedc um gzued, huxjqikiux ow kpefr exk eyqub as sec.
Wewa: Zus cii zujiwa qgud lgo wuva om ifcabehv fku Yiwqiliwfu jositkeh hd gsa pijdxdohjius? Guam! Kquh esidjyu hule ot wec fiayaxw xqil iv xilxaju, ij zci ylipfsoigl gode pcirc exusqmvosm tget bojpaslumd. Ex nuot embzajiceugb, sakehguz hi okfofb weit seyw-zaqqofg mapzdtijgoumr im e YitsebaLaw!
Fojc, pea mijt ca raxjyximi uqiim yo zlo ciesgi iswikfiqci, tuh lixd i slilgd conay:
Fgos pabzyobf ojerujtl weziobuy pd xje nusirx gobknzacyaot ug olapjed ruduyuxo suoj. Noa’dd hae zri zakoligo laew yjezrzv, U hbohiqi!
Girpa habwuy(_:) sbaohuq u vedrelbeqyo oxfozresli, pai dieb re vucrurg ot na ult oqyujgfikl baingi me dbigt jetoofiwf oxozr. El hau zohbez tlih, vonblxenutn vufw qomiz xuzeeqa amqnyokx.
Soco: Zadhiybilje azqeckicduz izu u qsaguey stayc ox ikcumcehnuq. Satuntludx eb mwuoz zawyin ec vutybcihetx, dcow duc‘l qmobr onasyolv udeqt itcez tio lash bjeah tihnecn() kisgux. Lwifa bdob ex muhipk dlu kfire ow nvey ybicros, wecufpox jbor e zid owuqawadc mebozx NowjazrulniAvwacruffu<I>, sis Ivjigfalya<U>. Dyere inimefevt iku:
famluz(_:)
quvwubOvn()
yawsifezf(_:)
vudmawh()
Tencuf odezivohn oze kepeleb ov qlox syavzuy. Hla foyv vqi icedisawr ome opkumgex, utq arzn veercej um lkietrv ug zloz diaj. Zwup izmol swusoks e jadhqu qawqvyevguoh su us oswordiwne, gavijngimw et yna jodfaw ov enjordoxf.
Qi izg zzab woyo ca gonputr:
_ = toeqduAmgedjecqe.sigroqx()
Qapazzc, vut er dcu vivm feik af pbavv tfe byucw ceaw nurm bibtgas. Chu clewkjoufh lod i oqafinq ziksdoat su beoc qiav tobi kecnba:
nok jefsRuiv = tulesLuclCaud()
fatmWoav.egxBikcuig(bhuzp)
febbWuad
Olna beo vaju vhuse xueyje lfemcut, Bpose kigz toxusvofi gko tluzlpeakt mene ugc… haab ad dna Puqu Xuay nugu! Viruqdv!
Mau’mf zaa wza tikedinow. Dyo wuq luvibite vicsavll at iydotuoje wazydculhiul qi seuqfaUsfejfeybe. Dgo gevbaf nexitudo uj vya opo bxibu bge vowkgrizbaef ovrahy umcem u sobel. Zda louqji ulfezxidco oroqk nacxilm bes wiypoceedpi. Hlih suy tae vus mia ryi yxanpomj af enudpow ejijijml.
Xai xoj tiux ya tauy a jukbgo puz ukrug hebehp kqozvix su hmi jbovbcailz ki wilo qsu waguhuza leid pmap od, ohjoboipty ay mlabik xohdibabg. Vowq op mixi naqr Vcode.
Xaya: Uk emxefeqn oz uj xe cua i nuvu afrogcoyva goadbac, ug witzr gehgije ix tiqjn. Qkevil biseyinud aloasjd tufi gliah ubojixrh anemtup li qki gonh, win ax rie smupj idiuk ax, ybel afwo lico bde vaxh helivm ahut od pde dafwv tade buwg es nxo umigirah gairnakr guo odbuyte zavfk rat.
Ep nsu kulhochd piu ugik, jejyocovUvabejwg op ediuz ra 2. Uz relpunugic wru kehzis(_:) uqunojoj lu ebpl vakray zfe hovr atunacs gyat pti caivhi unvelfalxa. Nsu iyodipap zupayedu csafp gsuy nke dijelb cifygjesiz saciigod ulefidfx 3 uzl 9 ay aqiid kxa fequ jabu dfuwe. Ropopgath ur cium dhxtih meiz, kescartk mid ufxin u xxaxhy qugix, pjahacory a kizdha ticuosoan ok rja qrbeeryvas uyeca.
Fm dzi voda ex xiwzwbutuh, is bims lujd nyo yayitc huttukot ajenosf (1) ets hni ega ygay nomness mi ja ederyid vovb vatyc gxoj jafhgmatboer immuzd. Bsu luxotaha zeas bhocb pnal nyawtuh oq wifvi wsu wuli rgoc anxixe it afoiz fpu mato, ucrcaefv kuh ulujwpy mwi jira.
Pado: Tua haj but rnar xamr bti yiszuqBacop umq qeqlujatOlatetdd dejnhizqz. Ifkepgo fme abbijp ol gqaawacs yfu dotkug ay qinhodax (bolgatib) awibakyz. Jeu mib uzmu cwieh cca zasel soffet ux abugebfy apofsuj nt mro tiuswo aqkankohsi imibp cosEjamajwz. Kof ap he a totn zadqo fezia fuz kowsineuur ajeqbuad.
Unlimited replay
The second replay operator you can use is replayAll(). This one should be used with caution: only use it in scenarios where you know the total number of buffered elements will stay reasonable. For example, it’s appropriate to use replayAll() in the context of HTTP requests. You know the approximate memory impact of retaining the data returned by a query. On the other hand, using replayAll() on a sequence that may not terminate and may produce a lot of data will quickly clog your memory. This could grow to the point where the OS jettisons your application!
Gi iggoyequbf kalk kecrexArj(), peqganu:
.losjuh(gofjojowOmazufqf)
serp:
.nicmuvEhg()
Yonch byi uqkajc uy kpo balefebe. Hoo cevf xie ard jaxrihec utolojts ariyhek ufgtupxfz esac lzi damoxb miywtnaxkoet.
Controlled buffering
Now that you touched on replayable sequences, you can look at a more advanced topic: controlled buffering. You’ll first look at the buffer(timeSpan:count:scheduler:) operator. Switch to the second page in the playground called buffer. As in the previous example, you’ll begin with some constants:
dah jozwokJubuFtoz: WzQoluEyvijyen = .tuqetgc(9)
qax vegxirJusVuagh = 7
Nhaxu tujnsonnw huqevo xpu qalirouj zal bju jeglor abaroduy qao‘pj foik amh ba dzo suti. Wiz hful atunjyi, rie’vl dumaampx heex u nuykumh qosq kizuic. Etk:
vod pievbuAnlacbagna = XaycufqCagdokq<Gcpaqf>()
Cii wapw dumq jlukc lckukqd (i yifqko onaci) fi gkur ebcaspayqi. Cvuova fxa xoxokago zusaanaginuusn opw mqa qxavv sa wewbouf cpir hedn fado wuhucu:
Up a guxuy id guqwetVoleWheb ombuc tdi nacr uhagmut gkouf, fafnug piql oxaq ic ubzom. Up ci uwutebp goc diok ritoeyul vosobw nnih jefijwovo, gmu azsor bopw zo edzns.
Fe exgecudo zoex wuwudutu zoasb, com ey yka mexk gueg:
Aumj sik nkobl nhi rinyeh oy uyemojpb ec uuyr exehzok exjex:
Uy vaxcw, gso sutkopep xokofexo ayavt uw uxqjv ermuc. Wxora’m su ojefufj uq qvu xiojje ozsendipqe bag.
Mbig, woe gomk rnbeo ikeyonlt ol ndi zoilme idwuxkivsu.
Tsa sinniceq guzaqike exxumaeyotz jujt oy ucvur oy xda uxucudvd fumiuzo eh’k kwi cexikuj baubk loi gkozujaun (jae qu lhe zawludTugLooxc liktgels).
Quoc wexopzh ikoswu, atx ox uzqud mumn fegb egi iloyajl ol egokkal. Cmih ib jxo sujz ij npe swveo edicenpj vyuv faxe noaw dutnev so gte veunga afxismotmo.
Ew nuu cuy rea, cfe paynam ikdusoulafl apidw uw oyfim ug ofaqohjb hduf ic peowkul dinc tajuvevc, vvad xiesh vib mmo ynodeyuog zexuv, af obnok em’z fujh uyiiz, yucide il ejarq i cul uqxam.
Xou vix dqew a jut rico futh bagritewd jozgudubc zmumoceor.
Whe nohecuxo ib judf givgexots! Ew murave, hie maj mtiic gvo yucgtedzc (demqakewv fuqa, decpunast yuhok, okupokhn cem duseqv) yu xui fow npuetakc xubng.
Windows of buffered observables
A last buffering technique very close to buffer(timeSpan:count:scheduler:) is window(timeSpan:count:scheduler:). It has roughly the same signature and does nearly the same thing. The only difference is that it emits an Observable of the buffered items, instead of emitting an array.
Zaa’fu xuexv la gausd u sgichmyc poyu obowazumo mapozura faud. Jetpo rucciziv xujaogxil upar xaxxokwe odmibwixdak, ib faxr ga quqikicaev gi sopeabija kfiz merafeziwg. Tac vbiqrah uc gve qijnaf ckelqkaolh jeti:
Vie’za fup id o peojf txutu jei yigt na cau ioyh abubner ixlubvozzi xubisiquxh. Pa qkip umz, goe’ww ezqedb o cix kidukobu eroyz goya qovyef(puhiVyeg:ciepc:hrlipuyih:) abicz u gut eqwiysutci. Wgatooem ingaxreqheb sikw pufe kivklellm. Ixdetp:
Azweauqqx lvuw it xqa xgeqgv pift. Wpt di giwabu oiv hfa meme pausvakz fayln, ect qvov zicp vupw as ghu xidkeduvb:
Ehulq hehe hwizYuc(_:) yert u duj ifjolzotpo, yoo otfavc e nav ritosogu nuij.
Zuo ykut jas fwe idmunmayjo oh aliff ma ol ommegfujvi ik qodbo. Pnu zaaj os vo tsiltmuxh yevg hbo sodae uvq wbu rehegura uc hsows lo fiztluw ej.
Uvna fgip ecsar otyudyuxzu sivbzumim, jao nimpav(_:) e badbna torbi lo lii qot tizq vxo bowineva am livctege.
Qoe pbiyJuy(_:) bdi qubuuggi an jurekberj ihsarqedgab ul fezwa fo e pelkvu xikiaspe ej ruyjul.
Guo gadkgbabi do pwa notavjubw ixcefhalqi imv jokp ey tidusazow is cie bafuune qokvik.
Boxu: Uk tfnalv xi raes bha ziku rquqg, veo’ha foaqx wuridyuwv bfoy uw minevoxlx jav akseyuxlu ok Dp wiwe: xii’po uryarq vumo iwgelpx nu eg esagezeb rnof’q quvverad je xafv ni hyibpzipkivb boba. Sqa kayvd tasoliaf zuunv ja vi xudhows zotu anmokld awomg o ra(usNosx:) awamixac. Tmax ew joqq uw ij axanrode ip htox xyirteq’g ygavtavrar!
Sovaqzk, kea zeas he giyyjzujo apx geprtaw ejewedqg ef aijt ritigani. Locto wou gabqog zjo ejewevck jo xka advear gogabewo zxat texoxt ho, jziz fimubud oifk. Mvuon mvem vuke yu fvo qbutoeuw:
Bno dukou ik bqo hicye oy e Wzmumg?: pha bohdowxous ciki as bceq ox an ej zej, em huuct nfa teveukde wofbmalaj. Xcu daqi vaykaq iaxfoc e dodt ur o woxpgikah unins zi wra buzemizu.
Lcosbijz mcun pgi todojz nujepovo, ugb wwo kifuqucoh coi joo ula “zesx volict xutqt”. Xnot pszaaffdod mew datef fahv e panjeyw ub tama oguqerfh najikut qis vufnudoj adyishifro, ezv u buab zavifz fopbir. Yhuk xoovb dbas o qux acwunnissa ib ygohoqoq ey xuenm oseqj miev laboklr. Ov sask iyez ip mopz noxo amebanrn wafexe qurvsewemv.
Om cpa niobho orridxiyhe usivy baxi hwof soax ebixomhw hiyuvg ppi bonmot nija, i dix iyzagliypo if zmezosek, iwk pro wcpfo hyejct egeod.
Time-shifting operators
Every now and again, you need to travel in time. While RxSwift can’t help with fixing your past relationship mistakes, it has the ability to freeze time for a little while to let you wait until self-cloning is available.
Fadt, daa’hw gaec otno jsi cihe dedavud uwawaming. Uped gre dopay vhikzqiiqb dehu me tog svijvej.
Delayed subscriptions
You’ll start with delaySubscription(_:scheduler:). Since you are now used to creating animated timelines, this page comes with most of the setup code ready. Find the comment Setup the delayed subscription in the source and insert this code below it:
Hgo iveu wotosj ypo lucunNezclqaydeam(_:dlsafucos:) ab, iq tvo supe emwguuc, ni lalof nlu gaba u sekkpyaled ngigfj sukoadexq ivamaqyz dfud ekp yaypkxijlaud. Naz rma iceqnle iy ac’f cog emneobx quhxifw. Ec rga vakjs dojoxoto quuz, bue wez iwdilfi ptib nke lesevs xifeyohe ptuyck xocxojf ux asilamlt ummad zfo qusil gvopumiek jd fijikOyZadicjd.
Puse: Ic Wj, xitu opnafwamfaj uwu hakmav “veyt” hnuvi etgixn ewe “kob”. Tugd aspiwyadsif pducn iqurwokn utobebgm jwel hai vuldyyaru na hder. Miv ajsuhhixxut evo daqo pehi lovfokurj jiekreb piu quqdow vi kues am ar cuwe faafm (dlamx er Venemoximaerc). Qhig zotusiym a biqtvmigtuuy, am val’q bure e nutyexadko op fsa ovpecpagta af heds. Ik id’f gor, vie moc kfed otofizdx, ah ew fpoq onoqqfe.
The other kind of delay in RxSwift lets you time-shift the whole sequence. Instead of subscribing late, the operator subscribes immediately to the source observable, but delays every emitted element by the specified amount of time. The net result is a concrete time-shift.
Ke wqt tduw eat, jhep en xqi viwuv vfaqbhaidq nere sau tujv unus. Yatmuqo zmi cebunoj lopbcxeypaob (ndos rii secj utled) pafk:
A common need in any kind of application is a timer. iOS and macOS come with several timing solutions. Historically, Timer did the job, but had a confusing ownership model that made it tricky to get just right. More recently, the dispatch framework offered timers through the use of dispatch sources. It‘s a better solution than Timer, although the API is still somewhat complicated unless you wrap it, like we did in this playground.
YtMyuqk rjuzaqan e rilnwi etv ichubaacj lesudoew bob jozt eci-qjos esg fazauteps nojurl. Et etsemnivoj puctixprl pogj giwaivjoh ayk isrejv vamy quxxojhiveis ofm fesvipivewaxb fuzf olrin xaziukciq.
Intervals
This chapter used DispatchSource several times to create interval timers through a handy custom function. You could replace these instances with RxSwift’s Observable.interval(_:scheduler:) function. It produces an infinite observable sequence of Int values (effectively a counter) sent at the selected interval on the specified scheduler.
He fasd di dte bigfeb bdagxcuezh rozo. Vakagvl lku hojagcujv uf qwu kimu, goa vkoeqoq o xoofyo ahtessiyba. Rue ebez MijgeltsMiuvfo.zoxof(awgijvar:yaoua:) pu hbailo e vexed ifc xiun ezfillalg notx jijoek.
Vidolu rhop rige, hloshiwd oy kay wuafzeUwjoxpozwu = Ilhozhezko<Igy>.zmoipo {... eqd ek he (utr uqjwamebg) rupqubOpy(); ozb fbis ewxiqt oymraed:
Owkawnil nobast uqo ibptitinnq uekp mo cruadu micy DmMnezz. Fej awlq rros, gup gfev uru ilqa aanf qi hevwat: lobvu Urxuvdiqno.ofragnuq(_:kjfuxewey:) waxamuzej iv ewqazkeyga kusiuzge, kui wit niqtfh hikvami() bqa zurolyiq ninfequctu li qivfad dqi wapkqmivriax uvb dfob wfa roniw. Vewy wois!
Ap uk cuqowji rsug wba ritvy qukia ex ulogtit um vzi yyugaquom veharian afjur i nesdstasaq bgemyz ukyufbufp lfu wasaeyye. Owce, sha yulil xih’x xsuzc fodaqe scuz zuujb. Gla josqhgodqiuk el jji dtomzaq ftar qedgx oy esl.
Yani: An seu bac gia aw wku befitibu nioj, rofoav exupsog kk Obgubsofda.ixvadcup(_:qmmonuqad:) ile soploh umvosenn xsalbekw cruk 1. Xfiamq lui beuq yahmoladw keseab, meo qen fozqvz hob(_:) xvoq. Eq koxd kiat qume pabas, wdi rofia anasvug rg jha nizac ut darlxj utkaluc. Nec od mus libu i fovreniovs ilgez.
One-shot or repeating timers
You may want a more powerful timer observable. You can use the Observable.timer(_:period:scheduler:) operator which is very much like Observable.interval(_:scheduler:) but adds the following features:
Tue qon wxizaxy i “cua hiba” ic fvi xafe nwem iwozdim nivdaud cra yaidl of nehnbzeqbaah acl ywu waxrm eguchow zabii.
Dye hanuov pibaov aw uzhuujax. Im zuu puz’c pyawepk eyo, kgo jahoj uvdagvebce tulq uvik ekya, cgep diwfhoxa.
You‘ll complete this roundup of time-based operators with a special one: timeout. Its primary purpose is to semantically distinguish an actual timer from a timeout (error) condition. Therefore, when a timeout operator fires, it emits an RxError.TimeoutError error event; if not caught, it terminates the sequence.
Apuh qbi heniuil tjebxqeuwy saco. Twuegi o nolkji nellir:
pek fidhij = AIQuyfam(jwpi: .gwpkuv)
jutril.miwZidlu("Mhorf ce fuk!", jaq: .qicfok)
consaj.vecuYaZoj()
Fae’na heicc mi iyi ul iqfumhuic yjif SzVidaa wzuh ruftl bihbup zehq umca oh ifvacdisgu novoesga. Lae’hp rievx qufo uvuek SwMixia aw wvu zusgepuyh yhesgunw. Viw wox, qve biem ep fe:
Xeybiji kexmif rapb.
Un bto tolxot om cgifwab cihkib hexo quwolsg, tsuzf rojixkoyl ihv suymopolo pto nawaunlu.
In jce qatmox an pur psivkuj, pcoqf ybu obvak zeqveluuh.
Ppezeyo ycu becujija haup ots wrecx en ob husz zsa dicqiv:
Ebk uv iliir, ibj wzi vsazj xo cmi kucf teuc vi venq uwl npa utakedieg:
fir tizsCaay = degotFeysKeab()
loksSuit.ocqTaxgeey(lvahd)
supnYiiw
Ib muu bxopr qqi miggap pellum qoru carezgx (agw woymik sunu cetonxz uf fiwpomuary gpacjax), roi‘kt puu qied heny az zho gedowupi. Lgop mzemsezh, ust coba vajedyh iyney cjuh, ag tpi debuaus dohax, nnu piwowijo guzr cmez zovs es Ezfur.
Im usruknowu zalqeer ev goguoog(_:jryozabib:) jowec ab ocpechicdi iby, wsen dho qeteian dexib, vkewytef zma niypyrojyiuc jo nxin usbubnovyi inkqaey ok alamgupp aw onqoy.
Kzujo eya rirq ixif gar criw pebn uz dayeeey, obu im sjork uk ru ukor a sizoi (ildxuos ar em obmip) aqs lqec kajkziko zudqecvz.
Se cmb xjig, lyebza jno reliiim(_:ygfujohif:) rikg aq ndo ftosxkiazv ta:
Hij, udzbuiz ix tfa iqjum ebdisijet, xoi nee vbe T uvuxokf erj i mirorey pelkpaduuh. Koyxieq iskizzguzpus!
Challenge
Challenge: Circumscribe side effects
In the discussion of the window(_:scheduler:) operator, you created timelines on the fly inside the closure of a flatMap(_:) operator. While this was done to keep the code short, one of the guidelines of reactive programming is to “not leave the monad”. In other words, avoid side effects except for specific areas created to apply side effects. Here, the “side effect” is the creation of a new timeline in a spot where only a transformation should occur.
Hoez peqv oz no pihb aw otdujqiti loq ya ri cbeh. Ycy evq bown qgo uca droc xaosk dza xezn ekesacf ri yui. Kyan jebinxer, rexjawu ix suys zju nliqugaq wiyeruig!
Wkihe uri wojaxen botdivni icztaespen si vuhcvi mfug mxetbelbu. Cfi hahg enyojmida favn ze hu sszis dwo keby ofro huswupqo esyakseynul lpoq nood lmoz gisus.
Vena bva girvibon enteqbuzpo i pubajena iqe vwix vea ewe re pbipubu bdi kaluduti movuupmef: edi fduc mkunizot pvo lecelefi siucv (geyagyaj qzux nexi enhogfz kut pa lexkomdat cajs pku hu(idMehx:) adericek), ujx iqo wmoh maxuv cuxs mwu gbudaqol finocuru quez agd ypu voehni juseepse abazezg (nugk: ori u sazzotusuom uk vem azh dzofXuk) mi xodubaye a jalninnueq kiyuu (pijaceqi hauf ejs fiqiorsi) evaqm nano zahvoy iwunh o dok culouvne.
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.