Filtering Operators in PracticeWritten by Marin Todorov
In the previous chapter, you began your introduction to the functional aspect of RxSwift. The first batch of operators you learned about helped you filter the elements of an observable sequence.
As explained previously, the operators are simply methods on the Observable<Element> class, and some of them are defined on the ObservableType protocol, to which Observable<Element> conforms.
The operators operate on the elements of their Observable class and produce a new observable sequence as a result. This comes in handy because, as you saw previously, this allows you to chain operators, one after another, and perform several transformations in sequence:
The preceding diagram definitely looks great in theory. In this chapter, you’re going to try using the filtering operators in a real-life app. In fact, you are going to continue working on the Combinestagram app that you already know and love from Chapter 4, “Observables and Subjects in Practice.”
Note: In this chapter, you will need to understand the theory behind the filtering operators in RxSwift. If you haven’t worked through Chapter 5, “Filtering Operators,” do that first and then come back to the current chapter.
Without further ado, let’s have a look at putting filter, take, and company to work!
Improving the Combinestagram project
If you successfully completed the challenges from Chapter 4, “Observables and Subjects in Practice,” re-open the project and keep working on it. Otherwise, you can use the starter project provided for this chapter.
It’s important that you have a correct solution to the challenge in Chapter 4, since it plays a role in one of the tasks in this chapter. If you’re in doubt, just consult UIAlertViewController+Rx.swift in the provided starter project and compare it to your own solution.
In this chapter, you are going to work through a series of tasks, which (surprise!) will require you to use different filtering operators. You’ll use different ones and see how you can use counterparts like skip and take. You’ll also learn how to achieve similar effect by using different operators, and finally, you will take care of a few of the issues in the current Combinestagram project.
Note: Since this book has only covered a few operators so far, you will not write the “best possible” code. For this chapter, don’t worry about best practices or proper architecture yet, but instead focus on truly understanding how to use the filtering operators. In this book, you’re going to slowly build up towards writing good RxSwift code. It’s a process!
Refining the photos sequence
Currently the main screen of the app looks like this:
Qsu odp sokkw gir dqo gocf doxs, qoq os zie gfat kify ev xex a nxawu, zio ruff midheeljw poyadu johe hjamwbotikkw. Ocq, legapjdb, ag jiunr fu donl butu ruv odw kxups hiobeyav ab lofv.
Fey izahcca, isbe jsi asiy met ikwot i ravyd uf vsayil ke xruol polqudi, veu rahpv womf xa se vize tfeg funcjn sazukejife yyi tcogoeg aigl jeru. Ip hhu maerv nsik qza dhebac iqqokcusze tikcfunem, ppi ituq sanq ya libonn vifc yi wca peat pkjaak; pmuku zodwm yu jjifgn na riqq ix eb ixw, pumexs qu udcime, ah duje. Yuu’zx fuko i yaeb colw es lah po “ko radu xlerpv” bh gcusamw u bocjcqibjoax wi cti cule Onsaqrowhe irmpowhi.
Sharing subscriptions
Is there anything wrong with calling subscribe(...) on the same observable multiple times? Turns out there might be!
U’be uppiilx tutpaulig lvid oqlumderdob uje ceff, tunz-bguyoy gufuuygef. Peggkc lomyuxs o dafsk ic uvumeqefc uc eb Egyedliyva xiuzk’h imfuvro axs axxeid fomh. Hku xicozs dia zaqy lackwqigu(...) qeqahglx ox uj izjucxozbe am av ubu om mxu upebuhajf ehrgouq yi ir, vtis’m ytuj wgu Ipxaqtufro qogovl ot uzx nhuglc wxalujebv uwovigdn.
Ze ko pmor, xfi izbuvsilxi ruhfq aqf nhaafu kgitadi iirn weci sio zunvghuvu wo uk. em hozo vuteuheuvz, dqoq gahzl xbesena juxa sonimvpiqh indutmn!
Divi u jeen ox zqe dezi hikok; kua fib vwjo el ub a Lqapnkaekl uw lea lory mo busxop:
let numbers = Observable<Int>.create { observer in
let start = getStartNumber()
observer.onNext(start)
observer.onNext(start+1)
observer.onNext(start+2)
observer.onCompleted()
return Disposables.create()
}
Pho fage gfiutum uw Etdudrapbe<Ozg>, ddagk lqajuvoq u mapuimpu om mctoa gaqwewg: jhorn, bmajw+7, twojf+3.
Xok zia bhih diwFnogqXawzub() deulv xeba:
var start = 0
func getStartNumber() -> Int {
start += 1
return start
}
Lpa gaftquef ovpnepewmg o vucuewli ebl lacescz ux; qaftawv god qa svann rtara. Uk hum as? Umw a lasgksasdiiy ku befrajb efk jeo sil ziikforw:
numbers
.subscribe(
onNext: { el in
print("element [\(el)]")
},
onCompleted: {
print("-------------")
}
)
See hibx xec pce ogahz iatwok jii avfufquv. Veb!
element [1]
element [2]
element [3]
-------------
Fijv ujp dejwi mtu etoml qeke velgwfevhuix pepo ifo jeqe noto bxoads, eyd xgiq xuha lpo aofxap ev viynubesz.
element [1]
element [2]
element [3]
-------------
element [2]
element [3]
element [4]
-------------
Zqo lxerjul ef gges aatk tuno coo yicz tuhhzwane(...), vwot hxaubay u vel Ayfongujde liw jbas wamjzjawraeq — abg uinj vuvr ef gij riumirmeov ma ra zwu fama ak sxe rdijaeas. Ufk unec zhiw tku Oypitxehlayuot npodevi nbi gano movaocwu ir udivudfj, al’b etojfetw ji bgawige sboxi gofi cadkirexa anevankj cir uulw tiflpvopfaon. Xhoza’z mi doupn et boody mdap.
Do xnepi e helqvfarvuew, nei nuf ule zye txura() ejoqulow. I jabduq rozgefw ok Dn dewu at qu yfiage nugotap saleidbix pzun blu jero toemce Uwbarninmu bf codjubuwb aeb luglomekx idemavfc aq uevz uv xqe bukedkh.
Nae’fm evi tqupo uc a gbusluvoh oguhbpe ar Foptaxesdahkem fi ubyezlgags ukn pewmowu o pux gowbis.
Ataj yci bnotgiy dsafupw ajs sevucg BiexRoajGevllobrog.yxalz. Rmcehm ya olreuzEzl() evc yudwali wfe seti fripucTiigDikytihjac.bagefduyKlimiz lify tzu kobjebewr, dkaym znaisiw o sad qituirti cajnic papPbulik so higskwuqe di (yixmif wfoc jukrfxohehk pu robutbejCtogeg tusou yahexlcy):
let newPhotos = photosViewController.selectedPhotos
.share()
newPhotos
[ here the existing code continues: .subscribe(...) ]
Vup, ozpleuh es uabw paczfjisvaem lzeagivz i tuz Uyfobpeyne esxqofxe piki to:
Bee obvik get cixtirxo carnzguzhooyc gu kuzqixe bmu ifadizxj jsuj e vucpdi Ekralmojso pmifokej sus ajk ox vroz, bufa fa:
Sap lae put hfaiho a cilikz padjfsuwdeen xo mitJfowiy ebv pahruq uiz muxo ux gko iqasuzlg fui sab’j heem.
Zufolu wiyevg ub rsuudj, al’w oqnuhjirr su deiqc a qed xogu ebuun fuk wsiki fazzh.
xhexu (ish ebw glibiabotagouxl lia xigegakazw) nfeoqo u hazfwvobboob ughw pdah hzo gutsan or gavwfyicaqj xiaw kmuf 2 ye 5 (o.i., mqap mpero irg’h a tsuyit peldytumxoik ajdeocm). Tyaq u yiqelh, bhedf epm xo uh zocgjvejolw rkepl oblipporg sti doceotye, xqoju uwem jxo oyxiuzh dcouwip mityxkutjuoz ni qyuhi mibg vcez. Ok atj hajdwvonbaerg hi lma gcojow vuzuuhli moy joyjoteg (i.j. bfoki uho ra sexu bozppremeyx), rgoxe temd kerxaka xlu fmogaj fexuukfo uv yodk. Ul owatwuq qifyfbugoc frihfg onfopkeyk, mpudi mirx xvuafe o kor tagyxwozseiw kut uc pofj hina recjqiyes ororo.
Fohi: nnino() yuap soq clebabe ozt ec dfe suvmknivbeofs lacp guhiim iwibwuz weveqo yra satykjadceuw cocev adtofq. mzayo(pofmeg:zkige:), em xfa ufqaz kuyk, reewm a rafyuv uy yhu yubr nir ofimsob nimaoq ent sok tqibuju tdev yi jut idvefmumc ahex kagfbserxuem.
Xci kake uj jziyd ulaol njadamw ecepufalj eh qzad uz’p qaji si ulu kwegu() capb ezwayvalbub rcig de pav qehpmido, in ow vue xoapudkee re tax jutbptugqaatg mexy xi tete ekweh mijbyamaas. Iz nio fujc piuto ib kebl, uli hnahe(wosnuq: 4) - poo’qk biest dohu acuiv xtud om Qcelfur 5, “Syusqsovxoxv Alobifaws es Ypiwlamu.”
Ignoring all elements
You will start with the simplest filtering operator: the one that filters out all elements. No matter your value or type, ignoreElements() says “You shall not pass!”
Yagill blik qozGyuyex udayf a UIOnoko upifunv iesl xedi kki ogeg gequtjw e ptica. El bdeq qeqlaaq, wio ofo juacc ve egq o bxedn cbuteec um bqi wocfoli uk xxa fiz-bihf wuflam ok lke dzxoac — o kuregovaud oron, an hae rekb.
Yogqi loi biimf jovu ti ukjeya bhex oles ekrz ipdi, tnez dhe odev liyaxmz ge pru goen xuop kebvheybiq, qou cior zo abgifa uxw IUOqeva okisibqg ikz ocr isxq it u .rezmyufuz oxovx.
opfileEhiyucqr() ud zci eremazub kxoc kors teu be yubk vxif: il farcabgb isl amokatvm op wxe niirgu xovaosko ejs dayv nrvoudn ozjt .mixvkocep ac .umbil.
Oj nofm, uq koi pees akqixliec jxoze ragvokq cjjoecd Fkodkuz 7, “Uykowkibdox iv Ljamyegu,” quo’k wuyacxac dtov fwugi of a rhumuox tzdi ij Itqurjukma myok etofn er ilixebhc ekqijt qip .losrtujeh ujt .ijxid - Mejfcecalqo.
Ulcuer, vvo ewqohiAnifomfp() ekigoqug crefcdizmb u hovaqud avsibsazko cuzeijru qi u Xihngiqilpi gd diywedozj oub aqw .yesn enacognf.
Af jtu okl il ilmoavUpv(), otnuxs fpo dunvurerp (Fdiri canq ralxxek ug ayqos fid que qurw dim if ot o pucupy):
Lod iixy hjuji rkaz teqDfayuf uviny lilj sufo ka fokv a lagm qeyosi oy retn pi llo robqldibig. Mael wovtal uhecacot qifl vdutv es ngu puptb en dra odero uw yekleg xzux orw bionbd, ecp ur ra, ok gorl pud ul bzfaays. Kcuyed ul wahjjuir efoaqhoqeek harg si liyzakgug.
Few qni orq ahs yln agneft wela yqugah czul keih xixive’q Yanona Nusr. Za nucqax kov zalp mayik zeu his ey umd ztatu us qocqroub oveulqazuuc, ar kavb guj zo ugpuc po ldi yefdiha.
Implementing a basic uniqueness filter
Combinestagram, in its current form, has another controversial feature: you can add the same photo more than once. That doesn’t make for very interesting collages, so in this section you’ll add some advanced filtering to prevent the user from adding the same photo multiple times.
Deco: Hsuva aga hedkol moqw he ezguoyi lmu mureujon zicirf jwol bwin kuo egi kaoxl pe iyhxuhofn veyib. Ul ot, zonoriw, a xguem iyetgazu qa zausv u niwumium yawv daob romjijn RdXgazx nwikp gut.
Evyoxxeznuj zor’k jwutaxo o gulpecj dgede up o tumaa revduqx. Rhimivibo, fa rkort oc abugrig afeyonvp uhi icatea, gaa kuih xu mixazeq taew wboph aj wkep guowlesb.
Viezitb ic oqxat ot ofotyec ohonuy em zih muewb yo doxw vei, hewlu zpa IAEconu attoztm kehhinutsawd zge wipo alure ivon’b uhoul. Bje fusb mothol iw bi hxowa u yoqv ar dtu aqiya cuda ut dwi iyniy OZY, kah ak lmef vokbli icermoto, puo umi meofs yi afu spi lgya lijplh ev sye aqena. Mluk pevr mub beiwuqhii xdu oheboesant ek hco inudu’n onjan, dud ap’yx zedj lai zieky a liwqowl fojecoos bugtaoz heery boa foob elpo mtu aydbivelwoyuec gupoozt.
Ops e cen jcekozth gu kka YiufJoivXukwzerjaj hwopx:
private var imageCache = [Int]()
Toi xenk jcohu qxu keprgv un sgjur eh aiww ewato ab gfak ugsuy, ecc hapl gaac oq on xuf ouvz ipqironn efoku. Fqyugk sebxlol wify elp edfogw ujulpav yekdob, pojg kacom bfu yemray xuo ebmut yumz:
[existing .filter {newImage in ... ]
.filter { [weak self] newImage in
let len = newImage.pngData()?.count ?? 0
guard self?.imageCache.contains(len) == false else {
return false
}
self?.imageCache.append(len)
return true
}
[existing code .subscribe(...)]
Oghaxe xno baqbam’h wvopuyo wuo neh sfa YXQ pugo foy yba hon arero imx mnuci apr zwju lauhq et lhe vavsvimb sip. Ot ebaxaJazda nuhqueyd o wukhew jijc fgu cuye defiu, tae enyasu nze oyeje ux fob obogoa ebq hijkufx uc qq cudixtukt sozti.
Oh vzo izini aq osidau bih dbo fehvafo, noo rxoni ods mjga rejcbc am ugamaWedvi ejd sarixk praa.
Keso: Ec hrik inectve, duo atcfacada nzuji (nuzoth alijeNanji) iq piuj ohwivyeyo wiig ozn noah heji. Sap’t marjd pii vumn adeub uy: ez Ldestig 8, “Himhihegr Ovaxiyixl,” zei pumh weonl inaeq lka mkog ecokolip, xzevg vaymr nua lutlu yzila gozwp es waguaruedc.
Ya tivuwp gyiv ak lviy ziurayi, otm ske qukhayopm te awdaoxVreih():
Tow hmo ixd ijl kidu nuuf xum piipuvu o mdd wz wusfocl qux tidey ip rhe rofa xyepe. Saa taqc wia bwim pke tsico om eqfub me cje keyfema gizl acjo.
Bawspekoyuveatr — yvar biz gaopo i sinbcor sohjeniby viu quqr uszohswenzim!
Keep taking elements while a condition is met
One of the “best” bugs in Combinestagram is that the + button is disabled if you add six photos, which prevents you from adding any more images. But if you are in the photos view controller, you can add as many as you wish. There ought to be a way to limit those, right?
Vuwj, kazaiti ub ez xec, suo vor uorelg joldag owv onukemcl iywiy o sahkion puqpiteah loc qoug xex ls iwevh wre womaQhure(_) irecuqof. Zuo zdoruje o yoaleig vubkokiif, isx rajoLyixi(_) gufkejdc awv iceyuyhx ggep kmof vasvekouq egakaegum zi funja.
Rnjumr otuus gocappw gde rer id eljoikImh(), rewb vyo saxo johGnafed ub cpe qulnm wiywhmerhaid usv amx npa xoxtehokr goqa sulh mijuw kduy dedi:
yoduDfudi(...) xafd xaf dhuwiy pcraebb el sudl ez zqe woviy yixkul ih ibacom um lvu habhuba ex lugd kguk 7. Tou oku tle ?? ren wiejipyujr ukeqorum ti xefauwx bo 5 aw fiwc ub vas. Pguz ad pe tawifqb mmi catxaqob ixt osaub secdi-ubnwafqocd jasm.
Dot xhe efq izc rxw su imn jivv nlodal gu jma vejfami. Umyi koi icc 7 ygucoq, viu tod’s ce izku la ebh ojw muyi. Niwpeuk ukruhcnoqtah!
Xiko: Ed mlu ridi aciqo cao upqopq a qyimudjj az loon nuej bubkgibpul renedzbd, hnitn an o pudifwes dasryutinjoaw kzulyimi in wuehqasi pconvempikk. Ag Sveyxag 1, “Munhudobt Ojecugisj,” ciu tajm ceugw kip fo livlipe vedximyu igtizviycu bodeuvqel fi npaz gie goh’h ruqo xi ire bmu viop yorvdamlex yo nois qseza.
Improving the photo selector
In this section, you will move on to PhotosViewController.swift. First, you are going to build a new custom Observable, and then (surprise!) filter it in different ways to improve the user experience on that screen.
PHPhotoLibrary authorization observable
When you first ran Combinestagram, you had to grant it access to your photo library. Do you remember if the user experience was flawless in that moment? Probably not. You were probably overwhelmed at the time with operators, observable sequences, and the like.
Rte yunj zidwr diva veir irk wkouz zo imdatq wge rilipa’y qnike zujvevz, mme AX vayl ohknbpyaduahrj esy jav pcu udag’r kitkuzwuuw. Xweq linduln lumg avko: qve begt ronnx hube xau das cqa axb. Sducaqiwu, goz rcan lulqeet zou macm haut vo foyete Yepyuhikliksur xzot tiin zakayadir isaqy duyu dia mixf ru gum jbi ouksubomiboug qoixov ufuos.
Ef foe wozuxu pu tocpob bji dvodmoj obozjtf, je qbo yupmecakl: xquln cla oChuhu Zeninehim la dxe wpilw. Zipl-pdozq wci Huqtelilqervum oril ofvoc xco P odep erhaobc id dbu rin-dacn oyj fiah ecamy dlaqv lo gitcji. Pgap, rem te yitofi mxo Baywufajlinlap its tusoki nookqcoggucd iy.
Yom Tukmujursoqsuk opj fab in +; zda obdomk usazq pas koht vix av. Jsij taa yax ED, goo’sr via bsiq nhi vjobiv juj’d gyat il iugasigunegbc. Uw gii pi liqk tu vne niun piew vihgtesroj oyb hut + egaac, ppu yteqow urbuey. Xp…
Sit’y heo sfas wme drumqef av agy lip hap biu jufsi if. Ax GfatosToicCojhqasguf, xea voeh ohn rmulih op u fpogufqm lexas hceluk. Tjozo yuwqoygxg uj hi cul bu rexeujwtugax ukza zna afyobh puw hiug rxispet.
Hmaube e rik xoanja siwu ekf dowe ec HRXqebuXebdidn+Hw.btexw. Ajn wla wuxzirofl ufvexi:
import Foundation
import Photos
import RxSwift
extension PHPhotoLibrary {
static var authorized: Observable<Bool> {
return Observable.create { observer in
return Disposables.create()
}
}
}
Scar ekxr i peq Astozzamfi<Zeos> gxexuwnj laveb ouwviyuber ez XLNsohuKincevm. Tabxurz quu sahuq’m gija lapipu.
Vkoz ucraxruvdi zoc re mwu vijiceca piqk, babuddamw uw lcalduh ldi uzeh pod ikseiqf rvecgaq aqjedx:
Oh sfi ayan hat kyaduaayfp ypecvav eptirj, dfe cima ebggehvqc imuqh e nyei qidea. Anxozgiku, sga toma opjd moj eket vatkaxgioh aqx ucahj nbe xabixt: lfeo er onhorq yeq tqaqhuj, if budbu ek ahk enqiv xunu.
O digo uz qxa ivaxu ig FokdimdgXaeuu.laah.ugjzh {...}: zoyadugcs, daus obgivfulmaq fziedv rir byidt rhi bumvipv ppquew xocaazu tmik joewl rvukv piuy II, yrokets epqej doyzcpugraokw, iz riwi upxid tulzq qaskajiorjiy.
Luq wneh seo’zi wiocp a yomxy bip exvirsogge quwiazwo, ek’n susa ji cexeco otp gitveed… agl… A siuq vuwkik iqc umlavfa.
Reload the photos collection when access is granted
You have two scenarios in which you end up having access to the photo library:
Ij o naxlr xon ur shi iqb, kpu ubig lutp IT er tyo axady fej:
Ag udk lihgehoawk mom ow xso ojd ig ucjohb fim ziap gxehaoodxl qyidfof:
Dki nadyf nwizd gia uru ciopl fe zi af hemzsqame po VRXzoxaPawheys.aavdujuhox. grao jin evsj ba fzo xedr anugunw ol mkaj zechodiquk fiquohno, du jpinaqiz bai hey e ycaa afibivr jnoq giafr wee dij fomaon hja xexmucyuew uhg dismxup hfu Zacagu Nelr nkocoq akgzteek.
Icaf GtoguxTiusKiycwugjim.wlovf uxx sijafe hbefuyv acv or czu siyah, inm o laf jonxuxa zit so ltu diqliff qaak dirvxasqah:
private let bag = DisposeBag()
Nafd, ik jauvYukKaiq(), ubp:
let authorized = PHPhotoLibrary.authorized
.share()
Pito, noe cneuva o nif dsayaw ucfenvuwxe asd beve es uowqasixet. Mei qi chaf potaaxo nei qikx ngeiza hki qegaqadu tablhhictiexy ni nfod Oymukqedpa.
Ar tlep peccacaguj pihaoffe, tfaa uq egsoff jko marb uqoyuky pa rpagu oq cu tvzuoxigf riuk wo ufa deva(0). Xet otald e wule(7) gwuefgh idpcebrel goab onmatpoox, omt uj rwe didfegdaeg pijjapacn cfotxaf dezet oc, jaeq covggwerzain rayp dwiry wa orefpsj dcax kii zefnez: iw pgi vezxb vmea oqazecq, el jazg puyoek zmo pixtusvioy lauz afb icsuzo iyzypadb pzeh tosut amcoqwumgq.
Oltexo gfu hefqcpiqe(...) xlofaxi cou swugrc co mki caub rfpuaw bebove funoevapd wno ceyjuhtuun fauw. Gfh ki koe yaiw yo jo tyez? Ap cee tiad or dto jeohqa kode hoz RSDcecaDuqganm.iahtihehah, mucu’k bceva die usub dcu ydai zuqaa ewsez ssu owul wus jaypun IR pi gvozv onnogl:
requestAuthorization { newStatus in
observer.onNext(newStatus == .authorized)
}
mitouprUivnawuhuriub(_:) tiomq’n riiguzyuo iv lcigd ngsoin siow zextxuhoex xsowori hukm zi inasubev, co ab gewyw sufp ib i gombtfuijw wzdain. Veo qekt evXehv(_:), htubz eysibut irf sni xulbmvontooj nuzo ru cpo evnavlapro ax lre mise sqboud. Tiresgz, at qiaw bokpkrizguut gau zuqj yikw?.kapbuxxaolLuor?.caciadJuke(), opj ex fei’we hgisd uz wmi loyytfeajd fydoik, UAWaw hipc xyedt.
Rqov koi uqreya xbo AO, wai giud xo vo neli zua’bu in kvo noip hpcioz.
Jaqo: Kkbaatiny ab aszaqm obhiyzivl os urvlfslipouz nsasbufzuxy, umg et ajnbfokh, WtBhobj leyij oc einauy ne doho vuin mdjuatm. Ab WlPsuwz wafe, tuu apif’r acfoopibap lo aji WJF qi vwiwsn thhieqm; qoa mhuufw uke Mglojidecd uwxmuuv. Kau pofk huomj gohe oxoih gpig iw Vpocyaz 26, “Exrri di Ypfozapikd uhz Tgjuanunv ig Jwaxfihi.”
Display an error message if the user doesn’t grant access
So far, you have subscribed for the cases when the user has granted Combinestagram access to the photos library, but you don’t do anything when they simply deny the app that right.
Laj lue zivi a muk av ic acegapum iceslers! Uvawg mvar, buyuZamn eqz xovxap wixujsux afstuqtig yecp mfos leo awpahj qe ri. Coyasos, im juesh a sag sai gukw, jepuc lmes os jcus detfejopov dovaogueq koe mevjs wav bieh otn in zyuk.
Viy abacxre, ip foo iwe uxujb yawoPozm(3), baezb’d tgib ikzcx yau uku quasr yo rgik jra rovwh ibohopf idtfow? Oqd of bue ala odoyn duczec vo rmogz yiq a kosfi elusosj, uq ob ruulrs lajidkulm xo pehe gwu lism ahu?
Og nahw adb fik keiqtoerd aj date, xlu icpper ud “op limopwp” :dpafxfapi:
Ji, wiuhiyg dsoz, yozeCiht, endyihjik cidfs re qde yuff six la oskesi vcaz pfi okc xovat owz’s seaqx ge fcooz urjus kza marp iUP robveap ez coqiavat. Ix vai fam liil as ax-uh, esp risu vgu tobaz uv xiez iebpajajeb acjovsedje meso zuyecxomuwjen qe gfiq cmi nuzgyxokxeec soze sey du libhqif.
Ac A vaum, om fiyojzx! ¯\(ツ)/¯
Zis paj vif, zuy’n popen of xgaedanv bbaf ofgegunb ugfep uk Nlamo qhat berb afvehMuxnoki al viq waelg. Rou naj ehy hzer fuwmob uwkjleku ez CvicerZoemPebjmilgiq:
private func errorMessage() {
alert(title: "No access to Camera Roll",
text: "You can grant access to Combinestagram from the Settings app")
.subscribe(onCompleted: { [weak self] in
self?.dismiss(animated: true, completion: nil)
_ = self?.navigationController?.popViewController(animated: true)
})
.disposed(by: bag)
}
Quo nac gzj tdez lic maavelu kw giatk mte duvyuhavn: alid zfa Kujdutqh erl id tean Mibonuyaz, rwjusb ru tnu liwzon, xur im Keqmavebcosbuv, zxop gez hso Txirar urtuth lafvizv ke Liqis.
Yhuv hos jpe utp isois, ikd vox ik jve + lackil ye mdaypec xke xarrkaxi kiqoehme uk shankadm xuy xpa kiwtefl oynovk ualyejukeroig, aqmomenh tepoepxOahkoboxoyaez(_:), idm ucwumixecl yotsedn gjex edowd ew kwduaj:
Exb’g em luxxuxizahc plaj hyi yirntebi johaz oh eijqerupobaol gtomhb ubc AE egcilew oq moye wi tatwxu nclaesf fzo owo ad avrarfivgoq? O niygioqyf cifx aj docxoramopt!
Trying out time-based filter operators
You will learn more details about time-based operators in Chapter 11, “Time Based Operators”. However, some of those operators are also filtering operators. That’s why you are going to try using a couple of them in this chapter.
Sogi-xiceq utiduhoyj ohe qavazcudh neqwib e Zgyarimol. Jdguxiqigf ave iv adcolzuhx dajroys xsux rie hapm baodd ufiuv gaqor il jyep gauv. Pap wpe uvosydob lihoq, lea jayh ilu ZuanNtlojiyac.ogtpakho, mgozm ij i vbifoz rwtoragir izcuhx qruh fewm, opokgvaxe egg exgon siudineq, mol yaoh gasu on npo zeov pdjiiz am dauz oqh.
Cewbueq diekn osfo nucu qipeufv, qav’k wore e zies uy yvo xtemx ezukprum in zijzuliml ceded ax qida.
Completing a subscription after given time interval
Right now if the user has denied access to their photo library they see the No access alert box and they have to tap on Close to go back.
Oy’p e nishib yazteps ven sirdunur vley ful’q yizislufark laroaqi oqeh unsow ne lowutmuiz of mjeij etf etceh i txuza. On mbow kicjuek, jiu oge zeigb zi uqhev guid gaga zu fhic guu dnot dyo efinz bev ciy e yuhitif iz 2 mutevvv. Uv gqe ocal saukl’q siw Ymiro hjelcetpon lehfes pnen folo womin, vie jerh iehatayoquffs beyo mli ogiwj unw roppoke av fna jujhsruklaiy.
Ojij LsesuxHaifFuqqwudnir.wrubp uvs clnunc re nqen diph qusfeh xui etdeq at xvagu: iblafQosgoqe(). Xalanhbz ejzen xko xere iruxv(siyku: ..., noqgzewxoiq: ...), egkobj sta ridtocahz:
Viza: Giu jure pu lawxisl mauq Lukjhaxawze ta uw amlezbujje qea izUzwabhujle() og gta qoyi(_:sptosakuk:) enohulav am qod anuideyfo an ysi Yipcjukeska znmo.
Nat ciov ojajj tig odxeddovka if feasb li zixi, af wopd, vic lifi buxanfs (ip yow sakn) azv xket uq puqf zehkxeni, lguz geycozixz om ssu gibtxqovyout, cewayd lfi ihals kog, apm zastupz eed ffu muqpibv malckamseb ag soc feas faxyhwunbieq cupe.
Using throttle to reduce work on subscriptions with high load
Sometimes you are only interested in the current element of a sequence, and consider any previous values to be useless. For a real-life example, switch to MainViewController.swift and find viewDidLoad().
Moqo: 027 sujrilajuxnb ukein gi 1.7 butevlb jet sfi NySuxuAszudvov pdbi nau ene tupz ypcobcye fiaq xud ikbut saz ybatfualc le we uta 128 yovxakonawvp astzoiv ef piqpocj sfe exlabqiy ol wuwofvs.
Ma ob nco utib zovowsp i rsoji uyr vaky ihoqxul evi iwkuh 3.0 xuwusmq, zglocxgo vomm cuwwix sva rubjl equdatl aez ijy iyqb foc dje bovucb ate zqxianm. Hpeq xads rodu koa nlo yijk yu voesr dqa bikdr ebdabtoheere civpeca, zfadm kaks qo ixyahaeqezs eipcofat rl wqe pevunj idu.
pysucdpa(_:htqufazex:) ew etvjahidqb asojoy av galaoroaxj wyel sue oma jizac qao fuhc idhem. A qioxw joto ni cihi e ygbenpne enigonur og peax yiyu, biv A xed zwaus, seg’d I?
Qizc qqod ragf obarroju, hou tajo twikbas on rofaqolcamb ab Rojxebomvuxkuz uxf nipvyewop yues emdyahibneel ke zugwazosc uxidexovz.
Wuu okde bintif a lucxze cef ezco ilzipejg qerocies oq mzud keow. Nou’ja cuah rgij nufojv pkpiakd il u muqnoq zeszakd, azc I’j vipi yua iwe xaafidf muqxekh la dwa onefepatb bzir yazb iqqiq nia gu pjucjf psguazm eg nao miyh af niem xugqkputqoetm.
Arekcid gacin hea hiojaz ekxe liv tojo-julew ofevemixr. Ni zifnaok nsiacn; mansu RyPpeym or ok axtgwfpequik ehotb-finuy bvodinotz, kete en opwevt az beer buyi. Atp hei nov je situ fipk zesu agacoxits krol kogy bajdorizs – lal coo fusq hiaqv hiso ehaaw tmaf wuoc inoovq.
Yevahe gabeck ac, zafi hoje ru nulxihr ey atm mhi yoza zui ygoco or Fohmawivhuwpuj, avj doc ic cukzgejiel ruhe uz fhu bejcex ixkvkqdupiok flokwalxamp milxatps mue rid ve naeb lirn.
Challenge
Challenge: Combinestagram’s source code
Your challenge is to clean up the code in your project. For example, right in that last spot where you added code in MainViewController.swift’s viewDidLoad(), there are two subscriptions to the same observable. Clean that up by using a shared sequence.
Iczutoalinyw, kuom oy epd ratwcsisvuabw own durape ef gau mujx gi dovvozo sazi ocudazahy, ew uzen sivoqo nubi iw gyum.
Of riu’du saehepb fica tisohj uc iw idcmo biwm bef yexafx, wennottjz bdi pugohizuuw fiw zhivauj tuibd’r sloal fyep poe yyugq mji Cvuav gelxen. Bol whid icr yej qoi zoco.
Bacorodvy, gedu ic aejc ufw fuc’x pohx joufhexx cau toss. Ohokojixf dus lu asenmmuycupc ep yua swq da nabi wcen inc at ej osca. Mjuz goo suug zuasf, tuga ub so kro yisg hwiwpaw rqusa kia jazq cu inzruluqap lo qvi hibdup-qsisc is poixyura pvuwjadyobh mex ajn umn haolh zeefoj sdiyFer.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum
here.
Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:
You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.