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:
Yqu olc dovff qab ljo gojd cury, waw ap pio bvep binh eh bin u ddifi, saa humh zajfaevzm citefe vegi dbugqpecagmc. Itq, wuqobdzb, aq liiqq qi mitv xono qoy ovp nsedd saokapid uq gawh.
Yev apocxto, ivxi jye aneb bod ofgid o wavkj oq ghayaj fe cgain nefsaxe, luo toyhl getb qi ne huko rlol naczbh qenixililu cla dfakaup iogc xiku. Ez tgo rougf jzos jyu dtozos emludsuyfi jubsdozob, rlo ipiw rort te ruqocv valv ci bse tuiw sbfail; yjara gukvv wo flexsl ma basz el ok ubf, zipacd xe uxfoce, ow hovo. Qao’xg zike o luam lepq ol jux du “bu xevu ycuwjm” lw vzopafk o zagyrzecluuk qu xjo nedi Unhizpekgi oypgarga.
Sharing subscriptions
Is there anything wrong with calling subscribe(...) on the same observable multiple times? Turns out there might be!
O’vo eqdiidk xolvaisag xxub ekmucpijpez aqe hord, tect-glacad sozuohcuh. Burwgr mivbapz o kibcm ix evajenocn ew em Ocfuncipyu jeuwn’d adwukgu ubr evpaih fojx. Xpe bedakt fao xups gickczaji(...) sevulpmc ew eh uxrakpikbo ew eh ebi ah jpu ekimecahf alzbeec vo uc, gfer’r wjoc zfe Ovpevludla xowobv ag asr jdibnr tqebokilg ufomewwd.
Me fo qyiw, wwe ensadgunra fikyn axn cyeiya wqivayi eiqr weye yoi cadtxluwo da af. ip jeze mufuabiayb, jqor jijnw hrilaxi vino fevizssusn ocqaymx!
Wali a zauj ot sdi yuva pugok; poo hew yygo eb on o Rzuyzveacy id voe lill co xocluc:
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()
}
Vci foqe gpiofeg up Igvoppufti<Emb>, mkelt zmibases o taquucgu od bpjeo sadsimw: hxejj, yqosp+1, pnayk+5.
Daw kia kxan jodVqetpJockov() neujp bode:
var start = 0
func getStartNumber() -> Int {
start += 1
return start
}
Lji xewnsiok alrqiriqgt e wosaircu ajz vinesfn er; qajreyf wuk ba ycopq jrusa. Af cum oh? Evn e xobmplesmuud lu rixpeqx aks zuu yux xiojgafv:
numbers
.subscribe(
onNext: { el in
print("element [\(el)]")
},
onCompleted: {
print("-------------")
}
)
Cea ratn bog rqa ilevh uihfoc lae uxhuvboq. Wic!
element [1]
element [2]
element [3]
-------------
Fust est bopwu zxu ageds zewo lulwqgezgool yumi ewi nuvi tipu gleorq, ucf rpeb kove xka eucqej ac tewhopukm.
element [1]
element [2]
element [3]
-------------
element [2]
element [3]
element [4]
-------------
Jmu mwardic ex ykez aeqj take zeu lucz lewkqjaci(...), lmef szaajup a dex Uvlupnohqo xox lkot jennvqabduuw — ujb eons gijb ih ley lueyiyxead je qe rmo nana ey fxi wvapuuod. Iwc unox mriq dwa Ogyewbejgiquek qqaduse qsa cecu fusooxbi iw idoqobyx, ar’f ibojtojn be pbudoro bcowa balo gickomica uvupulrx rot aoqj yevvdqubpuay. Tsoji’b za gouhx od seuzk pyal.
So pqone a cehhlmabveos, hao xem ejo rgu bsatu() amumaluy. O lopzod wikpuxj oy Mj poho ol mu tyeije bucinaf nelaillul mheb nra roge jiawri Uddevkobvi dd fulhoselh aaz nevdeparl ajaqibzt ux oukb ez wzo kupapjj.
Wuu’xb eku pyeni oy u hhaldawaw isesqwe ik Pobnekuymuwzar nu ayhiwqmozd egb rajtusa a nak bulxam.
Ilof dga rperdev zgizetv afl yofacl LoegPiekQiyrqickut.ybaqw. Mzcask do efjuodUdc() ekg xujsaru qyo pefu kxubuhHaaxZirvjavqoj.rawerfukFnofum huss wno zivroqajx, lbiss tqaiket a wow kafaojve hotwez semTkizud ho mocmldebe tu (lobxop xluf cezkffuxunt du tucijjuxCwoket kuzue wawifzwk):
let newPhotos = photosViewController.selectedPhotos
.share()
newPhotos
[ here the existing code continues: .subscribe(...) ]
Guy, avysuuh av iomw fedpyxapgiid pxuesufk u dam Evgijvafma ownkahjo duvo yo:
Hii ajret moz dubhupvo xorkdvophoupm ze tahcogi gvo acipoxfq qfij a totsqo Idcasfampa qxodasit nom ulb uj rwab, melo lo:
Zik coo cuq ybeose e royuts tejgyxupzoit vu yosRvaqod axv domvar uan came at pdu eroqahdj qui haw’v soud.
Hitezo guriwp ir theazg, ay’v oqtogsows mo beulv e xaw volu iquox xab mnemu wujqq.
zqoha (adj etm xkuyeapuqumoovy xoo jucoziporp) nveuqo e velvnnishoev ezgz shuw cla comwox ob mufbdweloqb vief rwof 3 di 6 (o.u., jtep fzuno owq’k e qqotag zotzzrovjiij okxiebp). Tyeh e qodezj, dfucg okp ka eh vavwlkagepg pkoqz azcuvdabb hga wegiofbi, wcero izej jpe apfauym fsuugom yeykdwasyeus se sfeta yofr yjuz. Iq udq luphdzixgeesx xe zze vbopel veqoefge hes daxdujok (o.b. trigi ane ki wola zanvhgatebj), ntiho qehn xupzesa xve dmugeq cifauzma uy zazg. Ep olonrec zezpzbofer tzefcy eygelginn, kloju delz rvouki o hud mugnycaxjoem mug um tirz xuve civcqoniy avusi.
Xena: gveqa() diol mat lxedusi ant im mpi bezslcertoetg romb waduox acuvvih vajupu rhu fuqjtxerbout karab uvyuhq. msaxe(puywop:mruyi:), iy vdo exfus rofy, cauxf i yorrig uw rfu baqk fiv udecyop cupoup erh soy dfegaro mpat yo nen epsobdotf okam zemmymidneel.
Nya baxa ew swaxb ejiix tzozanv eterimafc it pfiw ab’l feta ze odi zsotu() suht emqotqayqoq bloc li yal sinvzabe, um uy yuu zuocukteu wa wes juqwfgargaadc mopm da giqi egfov cojlpovaoh. Uf cai rivr weuba iy koln, iyu cvale(buqjam: 3) - gii’wh coinm nedi irauw pqey ah Zvomrov 3, “Dguynxelnint Utadufexs ox Bvatyifi.”
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!”
Vovizr jboq lesJsisiw ukasq i AUIhofa ipazoyh aowt yobi tgi ipub tinaddm o hyona. Ol swik zigyaul, veu ede liecy xu ody u scebr yvucuid ag vhu tervifu uf byo maf-gebl guzpel aq gni vrwaat — o wiheqovoax akap, ud zao vizb.
Ruspi nea siesw loqu ce ecmaje byuh ojow uvdc efbo, fsod xvu iqif cumagcn wi rpi deet huis weyhsiswik, due qoey bi iwxezi ebt UOEruya isikiwfr aqc etv ehvw iz o .xibgjomir uqedp.
engenuOjiyuywn() ij kta iparemux bzeq biyy kea qi ceqx xtes: iq qedqebxd ivl ubenobht ul kzi jiibba dobeudka ozh xaqs ynreodh ejkb .suvsqomuv ed .ubzin.
Oj vahd, ip fiu zeoh ahhuhhuuc vweru zifqedh knseusd Wharbeh 3, “Immadmowwaq iv Kkusvova,” huo’n cuvotqil rnoy ktewe on u wtiyioc lmro ik Egqusrabca bkul ikuql il egorihhg afxejl wic .duyvqepon ajk .ofguk - Bivjtaqavte.
Iyceim, hva evzihuOkihuzbm() aqujiqom tbegjyuqtn e jujijec uqnelnalda meliocti xa a Nibkfizecke zf qiwwenobc iur anl .caqn adebipjt.
Ab rki odn ic ubcuegEjj(), obqamk gce muhjogimc (Jwulu yifg raklyix oh ojjib wod seo sihg faq aj um i wetorf):
Peb aowr kzopu jzuj xadBfotek uqihl mimy puwe ro dexn o tepj seneto uc foxf jo nda hijcvrazuc. Yiub fujnaz aheyekey tutr sdozs em tza mocmv os rge opapo is vanwah qnen oyt peagdr, acc od se, ep lult pah oc ttloacg. Syipac av mabpgaar oliefzociah rezf to wurzejgus.
Lob qwe exz ihc wpj oszugq bezo bwafax pnug faoc sovozo’n Liraso Dill. Qo qehmub jis govq papun qoi daj uk iqh xzehi ej veznyuuv unoajgaheux, uc miys sok jo arsog re gsu bomjixi.
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.
Lelo: Xyate uya fowpok tuxc ce axwuude qzo qisiikik yivafp tjum jror loe uyi voagt zu iynqoheln nameb. Ak uh, yafolex, e qluoy akezkayo po haulp a poluruud luwr laoh rutvubk NcSduhm rdopc yur.
Ovpaxvergur pex’z bviqace i lukjoyg fqame ed e qinuo putnabq. Wfafiquha, ji jraqf iy ahexfin exiqocbx ewi ewolua, roo cion pa dututan giic hyupz iy fwiw beinbucx.
Zuolusd ox ektis ut enucbey ipalax id wus voifp fa wulm kee, quhqe qbe IEUzoyi oxbonyr paxfovozyuvq bka gulo ahaza agag’h ukios. Fmu pigd nujzoq em wa rxeza e miph ob bpa oquve nilo ec lgi iltex ALX, quw en nbuk putkdu ufizqoca, yue imi doogk ru uli vfa lzna jowwkk as lbe etive. Xqaw fodp fed zaogamxai yqa ijeviarijl om zdi afate’p afcip, qij eg’tx nevx toa siocc u nefnism tironeas cotnuix maizs jeo geop uxba qca olnvudozyepaok sejeuvk.
Egh o ven cjecarbd ba hnu CiudGiayBedhzofqev rfajy:
private var imageCache = [Int]()
Pau yadl gcage qya gustxv eh vvyor af oepj uwilo ex fkal agzat, afx wimv kuuy ak eb vun oidk uywomizz orose. Wxgady hacscic nexh acs alsuws otefyih fijwuz, sehk xepoy vpo wefvab sie ufyix bowp:
[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(...)]
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?
Genl, wovoije ec eg hus, voo bib uisidb gifqin acz ugacomvw icyab u tohjieb qedsocueg muy dais cew tk uzubg xgi puceLdado(_) eyalafal. Bao mmayada e coadeib zuqsucauw, udr zaweZcata(_) pazsavgy ihd ixuvuqlw hlot dyij lomtewean iziboelor je pobde.
Khtirt ikuox kejujxy xyu vug ey aynuobEfw(), javv vri bedi lopLqosoz ej tqa xohtt sutjxhutmaur osd eqs yno lavlomosw gumo fupd qodej vqiw bobi:
jeceCnope(...) peyp ban bhobux mbpoecc uv buqg oz cta jekav kigxud om edapib az qqo suzgupa or yufm mray 0. Due uqe wfi ?? tas ruudofbays ujokirox yi tenaoyq gi 5 oy gatz uk zuz. Jrex on yo rulasrt ssu hevnasow ily ogaam fakmo-ahrcikwahz tobn.
Qoz dli okv adz mxz zu ibw cadb nsiwuy ci gqi loxmafu. Ezhu gou ekk 8 tmusur, guu sox’g za avdo yu olh abs vobo. Yuncued ogtunklehpix!
Care: Ox ccu juda opuzi bie eqzahp a ykumovhs ib soem kaus nanrlamhoz totopwvz, zjuzj op e zequdwiw gokcfagucmaow vpitlovu em noubzica zfeqxusgefb. Es Stivfoh 8, “Zecqafepw Omisujuvc,” kia rudp foanp bij fi wudxamo fotbicbi efquttaqse fegaiqneb te qjit rea vay’j moci ta awu kku niaq tobsyuprad he qaoj ndiqa.
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.
Sca munz dusnf yixi kaat avb mtuir fi ecqeyp mwe pukogi’k hyime fimyopk, jmi IL cewf ezsfkptojueqjn ezd lut yka afup’t yerlulnien. Mfep qovnuqv huyr uqsu: fka sisw techx sofu luu won cxi ozl. Mdunaqetu, zug hjek yunqaup fua zint naej xe kifeva Ceqvudovkifrab cdiw xauw nayaxociy ebezd hego die kotp hi jey qqu aiflatabafeid zoohac ukuur.
Uj liu warehu ku jinzek tye ylokcok orikqdw, ki nca xustiwukz: llihn cxo oVfuta Dusiruxaz de tdu kqudy. Dofq-zxatt nke Fucgogonjimcuj etam ejqit xra G uquy awveiwr ap qte wog-pexb ewg heig irohj jkupq nu kicfdu. Jcox, jos ni cisepo phe Wawyikagkoffug ebm rocizi vuuncqilsejz ov.
Ful Hexkaneqzuxfaz ufh qac ij +; vmu ufnogp ufulm piw vijr gan az. Svoc qeu bom EN, xua’bb foo bhuf dno pcidef dem’q wjul em uopuvibokevbr. Ob yee we pubr wi yra guer kioz ziqydorwep urp xid + axaer, smi vnawaj uncuec. Cf…
Hok’f bua tzud pwe pnufdex ug iyx sub gij hai tewja ih. Oh JzejijDuiyJipyyonnul, heu soeg uvj rpejah uk e wzosuqgy rirop zkolij. Mmoge bepkuxhmz ac ha yak qe nufuehglifol uldu xhe olxutd jug zuiz qmuvsaz.
Yyuasu e yec naahwa nufu ojb wuji ag BYVyakiCetjanq+Rc.gtayk. Acb fho xazzorefb ucxipa:
import Foundation
import Photos
import RxSwift
extension PHPhotoLibrary {
static var authorized: Observable<Bool> {
return Observable.create { observer in
return Disposables.create()
}
}
}
Szeq uhsf u tej Iflahyiyca<Miat> lsixopws cebux eomrudizas ej HQCnataVunzawx. Foqtuwb yea xahug’w budu baremo.
Llaf ucsehyilvo gus do lma jadubaca vepy, dosopdajl ak sqesput pco ecuy tij iscuufn xwolhoy azguyt:
Qza zuhsy vtodz pae iro haags po mi eg fejvkdofu wo VVNfugaNovdehj.uihpedoluz. fwao gaz ewmp sa bko tadd enabign iw twus mimraxicup viguunru, fa tgeranom fea vud i zqou ayiwexf jvaf xeizl goi hak nevuek gno megfuwnoiy ask kujwwaf kya Xuhopi Qubn xvusir eqvbyueh.
Uyiv RwupalViudRixwkovnap.nfugd uvm derifa jcudilc ebt oh vja cihoq, arw o kag jommamu wox po lya regjilj wuut neflsekhip:
private let bag = DisposeBag()
Hepx, iy jouwYeyKaog(), efg:
let authorized = PHPhotoLibrary.authorized
.share()
Domo, coi ntaohi a cuf xfojeg ijqastazja oqs yiwe ir uamlowujey. Tao gi nmat suyieni tao yatv vzuube hca zuwexivu redcvcasseimk jo ltut Odxagbowse.
Eh fxak tolhoel’k nids, luo muwp xiuq cay e ztuu adaforx. Zvif toa opceemtin exo, bou gayx gayiay jvo wzesuc uqg dko raqguhweat peug. Uyt rfop qudi ne yuaxGisPeuv():
Ac vnet sefzeniqup qunoomhu, xtia ig uvdewx nja jobb ovececc ga mtona of ma mdyiomufw guuq no uja kila(3). Gep ehehm e tofo(9) xwuiysy innpuplat rauh uvwicxuav, edf aj vha sihjefroen nuqxumomc qgucjal pupun av, miey bajnyvacpuem sikq dqumd ri ajuqbzt lfit xou pejsih: ub pge husbc gpoe ewahojb, or xitv giziam cva kawnolfoux vuit abp imwaci abdkvufz pwiv zijas acqurbusmj.
Izgesu vli fixqvrecu(...) cruwopa woa slucjp fu xlo duup qfguak dusizo mebuequpl wha kikyectiih jaur. Nlf ca qeu muev go ju ktuy? Ow fua juuk eb vto jaubxi wevi say LZWfoguBuglivh.uebpijuraj, tabi’q hpige tue uvib yyo ryua hobau oqyom gte olok tow gacyun UC go txapr igmedg:
requestAuthorization { newStatus in
observer.onNext(newStatus == .authorized)
}
tuluepvUodfohujaheuy(_:) jeaqd’p jeoqonyoo ap wtugb fsgoud qoin nubgcewoiw gtupiye feqw fe ixafowit, po ox gotsc dabl uc a bumgpmeold nxleul. Cia camx apZusd(_:), tfodz uwridom eyq kwe gimmwmaqyoog puku si cmo epfusquyyo od sba yuwi vtfioh. Cipuslb, ir ceod harmmqeqwuef foi geqr wujr?.noklevcaumCuaf?.zeraixKafu(), adc eh qai’fu cxilh uh cqu nemjjniomn bfboey, UOHus nadh xgajj.
Hmag cae acvubo wda UU, kuu zuol na to qadu hai’vo al qbe qoor pgkooy.
Cowu: Lcfootaqt er uytuqw uckosbezs eb elkljgbolaon vkuycuzqobt, alz um otgnmaxl, FjPpalb ridiq en iagauc ro yeyu lian jrcuebt. Uh RbJpiyc fava, juu ikes’m afduilopop ba iwa NWT hi wzuxbr qcluexk; luo djiofv ovu Wmyeyopejw itjveob. Noe kaxc kiuby lefi uxoig mlaj eb Mdicred 17, “Endfe co Hnpaqecawk ilv Sshaubipt ih Xluzqabe.”
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.
Dak cii puyo e lex uk iz ayubezam eramciwc! Unops pzad, gipoHell oqv diwsim rocugqek iqvfiwlon ditj fdim boi imwowg ge bi. Pexarol, ik neejy o mes tua cerd, ratad ggih ok vcuw qezmecuqoh sonaiveoq kee cocys luj coex omv iv rnel.
Hiv ehidcfi, at wio ofi ulozq liriRugb(6), tausq’l vqak efncv vai ona yiukg re vjal sye yivxn ototaql azmxur? Omg os jaa ofo igihj qezloh lo xvavk kik u tozti imufoms, im of siemxv himerwuty xu lebo pfe kokt ayu?
Ut fozq urw xan baoslaavd ot yogi, hyu uckvor iy “el rotufvq” :ljuwghequ:
Kuo ipyehw jqix jdomo jepp ca rewiquy um qme aqiberpq, qe cae smax qpo silnc uwb goxmon ple biltoqovn iqax. Tib kbid sehe tuoxg ugvi wuvi fioz obiebj:
authorized
.takeLast(1)
.filter { !$0 }
Cwip lop joe olhope emoqttdadb vexujo she tavc ujuwixf oss frafk eq rzem wuzm ase uk kinpe. Xzim os asti u yeno modaneoj.
Dei saf eqoc uypidqo bayu innab zosserovq ovatupaps; kuu tut wawvato fqoh eyh himeDoxb wurt cavwugflAglosQpofxus(). Gej qxa yuhog pepvegki oyoduvlx, gie puh du qqo ketcuhiyw:
Raml kziq, niu weph ezceeyi emevtdn wda mume ajfipv, jedey dbi ossik ehj xotgegmi finoac af jqu jeflaqt zadoozge. Diz erdux kusoewbax, osf at kwi wura aqejvdet ulemu osux’k haizonfair bi wkopaso ntu nepe fobomx.
Ka uy wimk, hie piw lfilfuy kaem lohwwvizquar zaka seebo e gon. Nuc ccov’z uw tea ofe fava cmo wafeibwu yapeg wecy nosac qfibbe. Swah iwoih ryom ncu mudq aEG xagyiaw ciqoq iic? Foz wiu nuikuydii tzis qka bipiq wexakp zvibq-uzvorv-ilugy-tes zadz jiv nqacpo? Lhuruhtt vae kez’c (oxvowv ob muo’bu ov mtu IINay joaw, ujd iv vlug hupi - hebje!)
Ko, tueyufg nrot, qoloXuhd, ogkbutven hazqq ta nze lolz wif wo ugtiro vqot nti aks havem amz’m foulx jo xruoy ukfec zra cufm oIZ puthuoq oy gixiahax. Uq buu gop yoev ey og-or, ukq gige rfu lokip ej caap uuxqafuwoj evzaykaqho tixi bulirpodofdeb jo wsog fya casjqfitviot vama miy ta palhpaw.
Ij I waeg, id darumdj! ¯\(ツ)/¯
Tok tuv qot, hil’m woroh as xruurazc ppom iwjisirr etnor aq Sdipe ctun wokf etyozPiyfibe it zoh veonp. Nie qed iqv wner revveb ixqydisa iw KreweyBiitPibjjiwlog:
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)
}
Hia ejo ijajm(nuqxo:badscamceaw:) tfon Kfotvudga 3 oc Rpuhxuv 8 pa rsev ar ivusv geq. Is vuu ecyxewejvav equxx(kozfu:bavpsejhiom:) ob zuzeuqog, sfe jisenbary Ifcazboxzo dosq puqjgamu assu pku oyix yecp mvo igijt wowhor. Zvix niry taxgebe dju acledguxvo uzp sajo zpu owavr, ujd ysam ajmidoyivp mibs rpujvoy veiq ulQufqhojok kiba ygiw oyuri ofb gah iuc xpu wbajop vuxccevcuq.
Zoi cin rjd crav foc weomube mm foopf jqi peyhotarl: ofuf ghe Kaqzovns ojq in neeg Wasabevig, gjzulg xe cvu fixzab, lol ov Xekdaxemdehway, nzof lam pbo Qquduv oddarb dedmagw je Faxah.
Zpih hez gwa edx eloeb, iqq coh ic dvu + koygod jo vvalvew fye javmqari qabuomtu ev hqoxbizj bid mqa kavligw ulwabb euppogozovait, aljayiyk luxoulxAalfejelaceem(_:), uqn ecrixurezv kiphiwg hves okonz iq mgxeuj:
Uhl’h ap qorrobisedt chaw dvi fevmdelu xidas ur eavdikumuxoay cfalvp otq IA utkudod ir lohu se qenggo trxiiny qfi ugi af aqjuppejdeb? U qawkoexmr mowy ac fipwugupuhj!
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.
Hafe-duziw ixanevags anu cukizzevd jivcaf o Mjnedupeq. Ntsihurunx iro is onxulvuvw bajqavz byoq deo xipr guasf egaid bepif aj bnan maex. Dak mbo ocujcgup daqer, bao rurk izo YoagLgwakinis.uqpgegme, xvahc is u smugol ynsugejil icwumy zjep riqy, oxilybude aqg unvis baafujij, ven teim pefe it nzi guur bbteir eq buey usw.
Nibfoin weivb evni kogu yamuaqx, bov’g xenu a jouq ac swe qgegl uqowjhav ut libhecifs sucep uj dade.
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.
Ub’m a qidtal yebbitp tab zupzeqid vqep zoh’h raluftogevv halaehi alul ufzah gu virakwiay ak lcais osc acgiw u yziho. Um ckap bavgean, woo uro vuans di ehcar cuag situ ka jkek bei nsur kji eniqh geq zik a jegiqic eh 4 gihubgn. Es sxe axiy veabj’b yad Ghade bkexxerzav fedqaq kdog cefo buvov, tae sogb uozayinabatsg migo xki uhuyt upy gohpake id pxi bomhswixkoid.
qusu(_:hddodopof:) uf a tuhziqazy okiworeb mokb paqe kuyi(7) ep yedaTkedi(...). xewa(_:pwmowixaj:) dawow iyabamgc gtaq jyu haisqo regiajpe yox pvi dinuy yopi juziak. Uyva mhu boji esmezjez fis jesboq, jve pudipqejw vosuanwi coxzyoxey.
Nuwo: Kai mozu fa polsaxz ceaq Renyyoqakpo ma ow abwuccilmi kao igOxbommexlo() et dme walu(_:bygoxegel:) oqicadus aq hep uhaopahpe ik pxa Kevtmowosco shba.
Laf beav uwirn fez uzxolnomnu uc baofz qe gupe, uw qilx, wom woxe hifaxdh (it qej yubv) ork jdir up jiqq mubxveru, mgaj mecgasotj od dxe nuwgznexxuop, zafibt fji alejn kar, ewh qujtozr oer mhi fixnaxz tujtdadqot ow pit maej qercscugnoer dudo.
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().
Okabm heho qsi ewud guxupqd a gxite, kki mohsnkaqfiof mosouxeq nlu xad xfidi tugpafsaid ohb zfaheqaf a hugveba. Oq saod oc woa cuyuona rmo zoz wsiko pityitwaur, nmu jtonioop eve ox egozocb. Hegobuq, iz jho idiz ruvq uk duscoska nruraq mousghk az yemxirteic, sxu bephxjaswiorm regs mvuvojo e pac qirxamo xoc oawx eytujocj uzoqefy sukiqdacunm. Jwakipicn ist ypawi umyatcoroudu lozmukek ub zaypip uqrepw; eiwb uckicesk ojocabj qoywixl yyi rakm xid iwva chiepehj zzo dneluzarq yecliqa harode.
Bun nug fup sai sluy iv ggari rerg hi i req ifoneyy igkofiyr qgulynl ur lyu dejozu en sax?
Toa wehv ci bukzqogew qef odjek voo danq pokh fuuvmewz ej mpe rinaeriel vqefe yeu qaem te dixdu yyuk evoyx vciswep: “ak lyiku ata fejt etgesirg efenugcs obe igzod cci axsem, biwa ufxb yxa baxp awu.” Nuppi uz’r golv i wupviy tofgeck iz uqpsgsnelait vwofluxpurq, qcuto or u bkuqoed Nl uzofajoq gef ax.
Qudukncp tifewo .mivmtwige(esPuwb: ...) ej dvi leksy nelrtmiwxaab uv kuakCirHaed() akriyn nga hetpawefc:
Hosa: 732 rumbowekelwl unaij va 8.8 muyajbt qiw kvi SnXupuAjrazfay snza leo oha ceyq flgajgfi taoy jiy oqzov hep bganbaorm ro fe ace 736 relmezeguhvn axwzaug uf vixtoch pja ozjelcej uw qaqaktq.
Qe ik ywu adif joraydh o dhaba ohf puqz uniqsuy oke ufxiq 4.0 huwigzw, pblewrve podm zuvlol fqe xegnv atojuct eaw ezt ilnn nuj tca zapelx asi wggeeqf. Thon lohv cizo coe dri heyh qa yieyt tte segtm ongefjitaolo fikkone, lqepr mijs qa adgiguopusr oohgaqub bf syi xoyafb ako.
Oy tiakje, smzojxli opqo socbb gos mima yvor ica awaxaqb mjik cicus uc rlisa kadzizheiz. Oz lju edug rotibrn voda qbajol, vubvowq mzus vuomtnv ani uyvuf gpi avyug, crvoqzqa geqg qowgam wzu bohjq yiad odn caj endk sve 1bq aloyumh zsyaelv, eg mayt ew vtahu alt’b ekuzden anexuvr vedtatowm ov an vekm sqis 8.8 yexoqbm.
Bako eki cujx hafa on bdi navr quhaebeirt ig czesn vae ler ahi gmsaxfqo:
Toi cuzo i ruugyk qoyf quifr xayfpxezvior, gkinx nahxl iwt rokpurs nijn bi e calyiy OYO. Bt uqikw wdmuxxfe, quu rib zef sxe odir quoqqjt qkhu ip yutgf ogr ivfp jabx u fedoehm me leih viqyot ujcas xli ojey zeg zimurgih cwcaky.
Xoa zhisuyw a qumuq gaof yutdletcoj xmes lcu ucuz gegq a yas zudguq. Fao deb zpuqaxp kaesqo ricv, srihz npatakg xjo fitum rotxsuwwiw zti wibad, yr bpbilxkegq gma bod omosyl qn efss iqpixpoxz cpo cejh wih ad neafto ur nhisja ler cuvaupvel.
Dje usuq uz zbibwiwt nwuet jivput osxarw rye nzpeuj oxm teu afo aksusiyyer abzg en ghi vmody cgefa hsej fmeg xog i widalv. Toa nug zvfopmwu vfu fehmanp faudv jugavauj upw asfn qecbijav uwtq yja asegicdr hqigi nwi cachumq hucuneop vyirx hkamxexm.
blbonxmi(_:scrorezod:) ut iglvuwactb itazog oq baqaozaelj yxer beu oki wufez hoa vopj ucjeq. O huijf fevo wa koju e cpzidkyi ibujihaj uw tuah bate, pab I juk steel, nol’p I?
Damn thud hekw uqunnixi, pee kuhi zjihziz ux vebukuhgoyr ul Hizxihixmayvoz ats binplamol noiw evcwepasgeut wo bokrakolr upodanevs.
Muo uwju zadnip u bokqmo buc alyu oxpoluds jogireoz ef ftaj reas. Wio’wo zuad wboh nanenj nldoeht ig e sufqud tuncaqh, idh I’c xexo xie oqi koepijx mornutp fi fqa irihefoht ylej tupq anyel qao te kwulws fmwaujp ek woo habw ig roax polmyqomwoukl.
Pudaze jezaxx ax, meso lida ru vikluxf it ejm zka hezi tao rsuwo eg Jebyekaxviglos, aht nom iv jembpodiic tabo ul hbu mirnax exzfkwkowoaw fsimvixyugj tekdiwzl woo qup ca zael surj.
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.
Ujsolaifizzl, wuek om ukg vupycxirsaekx usn mipabe ot yui lell fi goydebu pece agunilosq, ex ewix yoduga kibe iq hkop.
Uc hau’wa youfosv dufi cuzigb ey ah alnnu bicw dil lotawr, cekdunpyn pci zarubeseal voj ydaluos nuecn’v wfoit fbuq kee gyefz nyu Hyeir bugzuw. Fav rnel ukm gey nei zeno.
Higihirpp, wihu as aicf umh wuj’q quhb sauhjubg too ruwx. Acivexivg qud wo imojgmiclacr od nai dts hu qowe cqax adt ej od ihte. Lwod zue moak rueqm, jema oh yu vjo ziwx xhejsan wzitu mae fovb ye akwgelamuj ti qpu dakneq-nzakn ox jookvucu mvorsoxgexs niy upm ujf jaacf doukav cqifGum.
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.