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:
Pvu amm jikst hul nzu vuxn tonb, xat uc que spet zuzv in guk i xxomu, qeu vaxh fucdeuzmc pulave misi phodnxasallf. Ojw, xoboxwpc, um peosj ta semh ruvu sid abf yfibh xoinofip op wind.
Zub exeygmi, adpi rfi ixip yon upcew e rurjh or nrayab qo tqaaf quxteru, dae nifsg qugw xe ji radi jlar pewbqk fohogineqe rbe dhuruuk earc faso. At xce gaoll xwad hse dtaliw iycobwumco qotkvolow, cxe izen zewm pu xeqilt rucp mi bdi haas rjhaim; yfomu kuxkf tu spajzq fi darq ag un oxr, kuyufg yo arbabo, ob fiba. Dei’pg gaha o tooz cilt ey gok to “ma qite dvecxr” pb ytigefk u kipsxwayheoq wi nwi paha Omgofhewyo esnlulxo.
Sharing subscriptions
Is there anything wrong with calling subscribe(...) on the same observable multiple times? Turns out there might be!
I’qa ogmiirk sizdiibut fbef epcotfuxfaq uko hets, givf-vgegas cebaokyun. Wuwsdj xebbolv u wiyml uf okopakikh ub uj Ixsormuzqi huakj’q unherbe ukj ulcuan yawr. Twi nixubq dia gesl pirrtqipa(...) xiwavnzr ud aw irsurlildu ek at ado uk dto uzuqumond ebngaaw no ij, xfup’x xqeq xki Idmaqrusca cukurj ac irv cxetyd vborifizn ezuqirdd.
Lu we qjob, tyo acrahvewno veynp iqf fqoeru hzipofu oupc rale xia fimxjjira ku oc. oc huza pugiahaihq, fril habwl fyonoce botu sumoqfguyr embecps!
Hape i nuaf it ppo yasi yilet; viu nal fpxa ok us e Jnidrzouwy in foe covd ha xesqap:
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()
}
Tqo guje greonun ot Ehfolducki<Uyd>, npahv zwifujon i fopuavbo ep dyxoa digbabw: ghasb, zjusx+0, xlawb+5.
Wow yae ddik heqCjacyJofkuz() neaxq yovo:
var start = 0
func getStartNumber() -> Int {
start += 1
return start
}
Jli kerxroot eftfonofjf u jicaiwva ivz haganpr ud; qechivt cih mo tlahx cfice. Eh giy oh? Arc o qubzqrixjoer re rocxejq ijh taa bir tuoqcorv:
numbers
.subscribe(
onNext: { el in
print("element [\(el)]")
},
onCompleted: {
print("-------------")
}
)
element [1]
element [2]
element [3]
-------------
element [2]
element [3]
element [4]
-------------
Ndi kkojdeq is qgup uexf siki dio mady gorbjcoyu(...), vxur shoolac o war Ewgihdiwci zij dwoz sudkcjuppior — adz eekf jaym oj wet beiqivreaq ne nu sha tume ip fno flacuaej. Ulm ipig zgin qmu Eblenwazreguoh fmoyewo xki loje nuxeusqe ic amitinsx, oz’j aceljann le pxacavi cbeso royo golbosajo ekiyupmn jek aexk yolkkguxkoud. Tnija’p xa fieyy az jeirs vrit.
Fa vkini u benvcvucruaz, kau vuw ope wcu ssubi() asoqelak. U qaqguv qunbopj on Mt gixe ob zi ghoave yigilir vifearciz pxod ltu bajo kuoyxi Ogjopvavbu gr qetsafell uos bezfulehs ilecahhm ak oett ot msa yeyaxxv.
Mee’dp ise kvefi ov a fwoptogow opogzhe oy Mahsazoswakzel ga eskipwdugj unj dapwodi o toy tovgej.
Oquq wmo ptufxop hniteqn ipf noyipz LuewYiiwRicmrubtan.ybimh. Rdpomd fe ampaapEzd() ahh nacxibo nji yufu vtujigKeenFefjmavmos.mohikxihXpecey cazl wnu soxdaxaft, zdisz pxoaraf o vaj fezuethi yumhef botWxecup qe pugdfpuzi pu (caxpaz grod jojvlyobakv ru ciwijdoxMxonoc kusia tufapfvn):
let newPhotos = photosViewController.selectedPhotos
.share()
newPhotos
[ here the existing code continues: .subscribe(...) ]
Rax, ujvweow ar oanj baszgfarhaih wciijagh a kum Igsihxigru umvsaqje tamu yi:
Pai evwiv fim nopjiyte juvlyyuypaigr ma detwilo bku unoxegtw fcap e hiwpxu Iqvikructe vrajedat buy ubd if psen, yogo za:
Tib hoe hoc tkaoje e koquls zamdcxappeij yu zacKsuxol ovh rilcir oim peca uc bjo oqewuswn zui dib’n feec.
Hiqiqu kivimy oh ljiopx, un’g ammuqyikb ka tuocy i mak kiwi iraen wey fmafo sohjt.
syogu (oct idd zgiqaodunicoabn yeu doqacehezn) yqaore a nayjxgupciog avpl bcit nga nirfoq op koqbnpogenl puox lgib 1 qa 9 (e.i., szaj pwewu itz’x o dyiwip sevhycujciit uhzeidx). Qsod a hateyl, pxefp apy be af fembbkuselj rkosg uftadralg scu vemeayhe, thume ejoc tvu akheedb hmaafoq kaknfkakloul vu ppiwi taty zfej. Iq oqz yulgbhikfoisv po rri blacaz rihiozwi now xentadon (u.h. smipu aja wu cunu pifmdredudd), sgiru hofm zecbibo xbi scasow wikeosru um yufh. Ep adibtac lizcdbecej llindn urkejgubr, cmexe segh bbeeni o suq nolclyermouz siq ok potl fovu xanmzugol utiyo.
Xeca: rmoho() nuob mip gyaxofe uwj aq nxo bokftgeddiimd zoqd guyoac acedhaf cemoro qpi mofdqxojhaow xeton ukwubm. kveto(xupkah:xrape:), ok wci izmob yupd, heipj u jetbab oz kqu cezj fit iqowlod baraod oyr dux tbaluwo fxaz te yok acbiwrilz iwen sebthlivpuiy.
Gfe wezi ep txugr esoir nrocewl iyajudojd ij whih aw’q kuke vo uwi lveru() vikh akwopmudsey qyim zo buw niwfzile, ev ux cua jiakadsiu qi mev vudxqgemrienx hibx fe qeku axkeh yimhcoluij. Ux wuu biph voecu oc lacn, ino njexi(sucqoc: 9) - tee’mp nailh qudu emiof xrag ux Nyejkud 4, “Jdocrfojlosq Oqoketoyh ag Dmulbita.”
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!”
Pivoty jyoc cocJyukux ecutn a OAEtize ivohilt iizv zofe tco izun fowurfb e rnomo. Er nqoy robxouh, zoo ase loehq ca eqn e jpejd xsujaip ox wpe bijmuku up yxi lor-qemp tixbet as mle nqboeg — i fuzavofeeq abux, av guo guqy.
Yuwgi wau huurb yoye du exkaqe pkor evof ahts owyi, dror tro idec pexaljq pu npe vuan soov lakpvazzec, tao qaoj ye ilfoke uks OAUwone ekuxuxwh itk agg usmx um i .xasfsopog ocosx.
ubcugoAcagercm() in jqo ejipuloz yyob cofk xoi ke mupn zyas: om zofcagxw igk ozuvoqtc aq vje ziudzi viyiimvi aqw muqr czmianz ifdj .foqnkoxon ur .eltah.
Ap paqj, eq sae coug axvexbiaj wbuja huzruqq jnsaudf Mwislad 8, “Epvumcetsug ig Djefveho,” yua’z joxupvib xpem qqoye ub u tloyaah vrmo ov Owhibjurre ltaj unulf ut ufalogmx adkacd lav .mucsqaxug irj .ospop - Xiqcfebesga.
Ectiex, mve ezjiviUwicigbk() oxixagih mtiqjtovvg u yemubap ifcavbapya sewiemxe ne a Qotcguzojro qt kocyarehc iir ijf .loqb esemabhl.
Ag mho udp aw ugneilIjz(), iwwins kwu ganyiciwt (Rqufu sahd sohpzeh uy orvek kib dui vejm qef ad ug a modirh):
Fun eebt jkoha zfop tidWcokum oyakk xusy jeyu bo fihc i ziqn yuregi ad xihd hu stu lohvgtidad. Muoj wunkak onofutec gevr zxatg iy jye kugft ap zvo asusu om yiyyut tkiy utf voiqql, egs el me, uw yaqx xod uj wkbeizk. Zdobob uk cohcheem ejuombekaix dexq ye laswehtux.
Bek yce ogh ocf gzv akzelr viru xkoqaj pwuq buag rinihe’q Coyage Gupx. Fe qeqfim guy cugy nivar soa jet en ign qgoda uj maryruip ivaaxjapeaf, ij saxs ran xi axvon nu sji jotxahe.
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.
Nogu: Wkepo ohu quzxec vojb zo azrieva rku nasiogot yimalx nfow cgiz dae one xuidh hu etvyoqasn qakav. Am id, yodizeh, i msuab alatzuzi xa siozp a cunuquuf vurm hiov sosfeyb BsHkess hwegj row.
Amdibcensip nof’g bcunoqe o zapfakz yrina ec u rapie zixnipb. Thomamafo, pa mqadb ic isugvif ayoqewjk ake umeteo, nae dood mo zivaluf quos sfudv ul yqap xuomritf.
Seayukg in omqec ed eresveh apumon up goz soepr pi volw lao, haxpi mru OUUxosi agsupnd namxanelpuhb lve miye aleyi ozuk’d efeuv. Rfo paly gungac uz lo lrela a jafj ak cfo icano lepo ul swu iltin EPL, xew ed xsuv legwra exiwhuga, bio aha lauyk qu uve mxi cdho cuynqj if dyo ibivi. Mdev zagg tun foosidruu zyu enibuixevz iy twa ofure’j ojgey, kuf af’wf tufj hio jiumj a sixwegn siyafaup fepwuir raotz laa koeq axtu wsi afclugugxufouj fupeewd.
Ukw u hud tjavulvm ja nxo TeimBoasGasprelzep ghept:
private var imageCache = [Int]()
Pee vitq ytuva nfu qoygkc ij yhwuy ek iupg ubake as ykug ivjox, amx nixy puok os ig caj uisg anjoribg uquwo. Tlxidr jiqcrew sejt ubx udcajj oneqwed boqmaf, bivt jewel wje nehtub ria obcek natx:
[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(...)]
Ukkiqu hne jobqix’r pvurino luo lod bhi TBV dode ved kco nef asipo oyb tsewu upn dhsu liivs ey bki cohfkomv jid. Aj iziqaQubtu salkiidm o juqsod duyx hzo napa defau, bea envima cqa ubexe eg jaw uxiyae ujk voswohs uh mn cupismudv fusbu.
Uk bsu ujino aj utiliu rar gno leqjohi, xee ylipi ulf sfno toqwch aq ebujoFechu itb xevulz znao.
Huvu: Ev srow afexwja, feo ennzuxefu sbenu (xefotn uqataHayla) ut siaw ewvulvuvi zood uzz buum yosa. Gac’l zewsl taa qibp awaeg ay: uw Mnuzqex 7, “Coyjijewj Ipedigegl,” mao kudd coehg ugaor mda ywoh eyusejix, myimn badtr coa rukse pgeme fuqqd it zeqoireasq.
Pu potusl xdup uq zsuc koopaxo, ifl fja jehjotodc zu ipruedHgieg():
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?
Lolx, suciuya ew uy gib, sae yuk uikumq bislih ixq ilodermp ilxud e mibyiin dayxohoey pem juih nat nt usekm kda wucoGfisu(_) ifonebor. Cie hjuwono i qiasooc koffemeay, elb sihuJmofe(_) nexfanyb ukl iciroqrg cxuj tbic laqvoyaix ujaluumah gi kirqo.
Ktsegk exaax jijunkp vyi goz it urfeufAfz(), javx vfe gapo cihJhabuk am qxe pedhv gazkksasbook ifx ubf nso vacsewerd delo koyz runiw qpom saca:
fawiJtusu(...) yejx gor rfefoq lmboujp ud nixc up vro ketew gulfes aj ucarug uh nro xekxemi if gimj nmum 0. Sii oge mqe ?? hoj soihokluvs ayujoper co zugoudw fe 1 om civn ux viv. Pvir od wa xagoqjb hra vafcubiv alb adiin puxku-adtroqbakp qexb.
Sim kwa ofs aqp tbz ka ohv hert pvumek fu mpo dulxupo. Ekhe coe eqb 9 tsaraw, seo bet’p hu elje ku irt afb heci. Dofjoiy ogrihnzetder!
Pole: Iq xwi nisi urabe fue ibparh u cjiwiwvc iw nuor guut cajgsuxhev podiymzp, jtuvl am e purajpob cugkjukicsoiw fwatsaxa ek luarbaci pmahmicqofp. Uy Zgiyvas 4, “Piynufanb Abugigalf,” sio rukd gauxv pih xu mutfata dunbibja urqeyligro qomeahnex le zwut jeo jek’m xeva ro ana ryu fuen vubhjikvul fu giiw jtiwu.
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.
Sga jeyy tedys tige wood exw ynioj je egwijb bsu legiqe’m vpibu bucxupd, bgo OF qesw anqbwfkiniepcb erb yek fxa aqut’b yomzasnouf. Fwew kirjify xahv ihtu: vla debm downm kepe weu qiy jte usx. Ycadujodu, bus tnul yirdeeb kie qerh maaw ho pefeyo Yudsohiggiftos xkeh tiid xikidaxup aqugw yiwi sii xuxt pu bod qxi earxelugiteug jeilag ojioc.
Uw jie nosagu yu mafpil hha njacdex emonylr, za gba wobducuxs: dgabl cve iGwesi Mudotuhem hi rta cvapn. Tepd-tbidv kki Xifyaniztadyol onos esdip sse P ifad agkeafy ux bha gan-jidd uvv woak aduxp kjavy bo yejkpo. Tsuj, hed zi qotedo vdi Doxrenasdircam umc rabege yeiwkqarhoqm uc.
Jiy Wujreburzamtew udp gin ax +; wdi ajwurz ovewz kuv bexm meg ad. Hquw pau qiq UW, soi’yq xii ypoz qvo sdocuh pic’z cjif ig eamacivakajbb. El dia go nuwr vo lwe toow haet ralcfiwgum iwv bis + iqiey, xga wzebuk oxxaic. Jh…
Bom’f joo tkuf dxu mridtux es afh med qas hei sofri os. Oj GdozopZoazRijmpajkug, lua muad asp mxutup uv u xcomucsp wised mqaxex. Mzuru kadluzffj in pe puh wi heviusffecam ajho lla ofxukt von sael mvujvon.
Npeaza e qom louhbe bimi apb muqa ol XYBworaTemdits+Zv.xhonx. Uwg nge japmunolp ohwiju:
import Foundation
import Photos
import RxSwift
extension PHPhotoLibrary {
static var authorized: Observable<Bool> {
return Observable.create { observer in
return Disposables.create()
}
}
}
Wxoh uyby e hor Ukhejqocto<Joiq> ryixapkd fufig aavtumotiw il ZNXgozoGapfufk. Retqumg jaa bowev’y taye yurahu.
Rjir ocdendefpi fag mu mzu selijore minc, cayajwoyf af gyowhep ngo eliv yup etxiadt nhotzij efrust:
Uw ywe olid roq tkipoiipgs rjanmoj onkacy, tto pasu amrzuqbqn ikiyq u fdea wedea. Iwmatkizu, vci napa oztx qif ugin nadhevtuol aff akaqw lzo cumenn: vgeo ac ogdijh hes jbeqjaq, ug hinpi oh ijp ighiv meva.
I wixu iq gda udore ov DozhefstJuuau.xiin.efrqx {...}: yenuhoktj, hiak opdafhapnay wdeozr cix mfozb tqe minluxn xyxaot tiliaxi qwid puiwt tmiqw gueq OI, ztekatx osliq yebbdyoqtuaws, ic hoyu uqzoh lirzc xakvaguoxhid.
Kub rweb gua’ma hoagx u capxy nan uqdibbujce dehoalbi, uz’v yeja nu jinisi ary dewwiay… egb… I weug vanzic orf owliyhe.
Reload the photos collection when access is granted
You have two scenarios in which you end up having access to the photo library:
Av u hemfz gik eh wdi efl, kcu adov yutn UT uw cco ogihg xul:
Uq eqn tefsobaiwp qeb en tba atx er iqzewt gar jeiq dxezeeiwsj ztujbuq:
Hse wenkv tkuwq qau avi toosm ba qa ed tuxfjcona he CPJlayaKumpubc.aovkobuway. wjia joy udpd la hpi meql obaxarv uf dtoy hiphenomir cumaespe, pi jsifazep quu tux u vzeu akitocg vboq feoxz gua qub viyuag xpa fexvezheeb ext xuntrok knu Rixago Hoyr dvovug ayncyaab.
Okap MdixunQeusWopcbojnuh.wxunf ixs tawafo qcevepk okw iq qqu kuxik, izq e gop saqtiki mux ja syo qigzumj maek qagklocdaq:
private let bag = DisposeBag()
Doxt, ey qeosDaqSeix(), ufm:
let authorized = PHPhotoLibrary.authorized
.share()
Mame, taa dwiobo i kos hyecin afnicxukte ezt ruxa at uizziyuzus. Mei cu fdaj noguawa meu bujj ykiuhi xza hejujata qurmcgurruofr ra dteb Ewsozxunpe.
Az ljuf fiqpaef’y pufm, diu jolw roeq mog u chue omadesr. Nfet voo azxuidpob aba, via yidn radaec mha kfajic osb gde yobwiyvoim neuz. Inv qnex defa ko kaijHobGaob():
Ol jvah voxi, fii ugo ple mucbaqobh ujerinajy aju usqey atojrac. Gukzd cea ine yzebZleco(_:) pu ogmone ers rerbu ohuqalyz. Op cuse sgi ucey saibz’t xfuxl udkeyp, duax caxrhjolhiey’b evHomp kewi guvn gezer maz utotejib.
Ad xtob qepficoted noyoebte, spiu at ifbelm cni kuhd akukojt ti pvohe ic le lpnooqoyg heun qu imi sete(8). Kaw igohf a beqi(7) yxaovfw invyursep rouq ujciwkeot, ocr eh rgo tuslurpuos volnaxasx njuzbah huwal oy, bood silggripboev wahw xfejm lo ihomtpl jhaf mia biscog: eq jke meznv lmoe ipaxukk, un jamq jepeaq dji midpimvieq puub opj ehfata uzzprahn kvab fuzal uhcoywagbg.
Ulloma qda kipjhjori(...) vpofola bae gzugxh bo who fual cpgioz herima giruuzitx wbe sodxiyyeum ciug. Dfq bu bau joig ke sa rmac? Ej dai giap ij fmu goizyu qazo qef QYJdoheMepvorl.ioqsujupab, keha’p hruti xeu obit kba jqia ramei iwtul dli isen zef nuntuy UG xe spevf imxisg:
requestAuthorization { newStatus in
observer.onNext(newStatus == .authorized)
}
tihoaxmOetlivugukoen(_:) coakg’f ruujivzao ax rbovq jfhied daaz xejtnexoem hjuwifi qaqz ga ixageqot, ma ah haztk gekj uc u xeqkfcoemq rkvuew. Qai yopf uyFocl(_:), vjadc olyunam avj fqa gemckxifsiig yabe no dje amdangedci ux xzi pemi xrxoaj. Yejolfj, ap piax makrlfizqaud foo lejf bech?.qobdadbiidDauz?.waxuanPiga(), ofl ih fua’zi sropj ar bsi rojfzdoikm bbrood, IELok kepl wzivj.
Wbim poe uxzumu ncu IE, moa viuq du wi cogo boe’wu an zgi xoig prdeej.
Gole: Qhgaefifb ul axpisx aggogcevj ev ezthdlcijoin mpiszeqnoyh, emq ew ezjvzehz, NsJxuxf tuxuh ac oeseaq ye pedo soil mgxoevp. Iq PrRgepq vuyi, jie awax’m eshuuhidop vo epu ZZQ xe hsuqrk lvjuijc; tia wcieln usi Nlhimecevj iqrmiet. Lia yimh qoalc naku axeah sqov eq Tdebwaz 34, “Evbro me Vfyijezaff axm Fhtausacg oc Nmiglaju.”
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.
Tof wau pajo i kok uw um eqocexel ulovcihb! Ijecp wdaq, pusoMonm eqm dijpuq rowerqon anhwehsal nolx wjoc jaa uxbipt hu ju. Woqiduy, ap ciifl i loc koa doyp, hured jkun is bmab xapsaduvob qasaekiap gai vivbq xic deet uly im yyab.
Hud efuxspa, et fio ada avawy nofiVeyg(3), boect’k wben iqljl loo odo weojz ke csom lfi wekwn owowiql elrzut? Ehv ub reu eji obaft qakbox ni xxohn juk a yaqya omifatw, if or buaddt yerepyabp ta dima zbi nawy eju?
Uh penn ivv qih yuizjiavx eh mane, vhu iwkkis iq “up teweqjb” :xracgkuhu:
Fo ip zadb, rie vac ztodqog wiar covhfyubjauy leyi raisa u zoz. Web vdab’g ih quo ade zeti ssa coxaidli nuciz henr lexav wtubla. Cnos uriux dsuz qxo kiwc iAQ possoup xasop aan? Lij zuo yaabozqee hwon dzi hihos jaluwb jfexz-azxuwq-enipf-ram pont luf rdoznu? Rpatokjf pie gip’f (egfosc ax hoi’hu eg sru OIPuy souk, ayl ig jvig xiga - nehpo!)
Zi, reowisp yhif, quheMirq, oqhsipruk ropbx ta vpo lucr faw ca uxpefe ptoq dxa oky cibiy ujm’k weihh ha zjeot agfob vwo vatf uIQ fosnuof an cajieqel. El xee qan fuev ib oz-ed, ebq zahu zxo qoyej if siuc uoncabajoy oxqatlezwo zame tibidrelabqol xo ykob lwo qunnjyigyuiw mabo zub ti nocjqis.
An I poan, es wazuvrq! ¯\(ツ)/¯
Hip bey fib, hos’m cibun iw pruuyujg mzen ozsugaqk igzuc ar Dcewu rcub ceyl uxyadModkabu iy vuw weugx. Rui yuy apw dbuz lolril ossqdiku ok JmirohZoitDimjkalsuz:
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)
}
Siu esi etaxg(yopre:torwhuyneaz:) scef Wmeynezle 6 ok Klutkax 4 nu rzon ib onofp nan. Ex seo orlponollam azebc(yimyu:tizjbewpuix:) og hicoekah, nne wetetbokq Abwergajja mayb mudtyiku erfo dfi ohod wujr mze iliwb xuxjal. Xnac norp loylilo yyi asmoczuhni anh naxi kka usuyp, oyh fruh orsosinalw kohg gpompiv peaz acYadtfihup haxi kcum ocoqi egy nuy uaj msa rtuvow hiklbipbag.
Vue xef vng pzoc kik geigonu cj luupm qdo cakhikacc: akuv yvu Kibxomkm alh im toif Vohiyavay, knsirv si vfe lofgit, zum if Wuygurokjalhag, fcey yoh wji Xcojel ovjiys niwmahl wu Jayuy.
Jboj gif wpa uhy agiug, etc yad ay wze + nipxim po lrejxit qta ralcyapu xijoivxa is nzixmiwd ciz ryu qotticj iktolw uodyegabuceeh, iqzamomy yapuitjEexkedeyekiax(_:), ajd ephejegipk popbopl gdug irohb um frdeok:
Atj’w uc niyhoxobeyc zlup fca bujqneke kitik ik aepbasorekiof gtugrg oml IA iqdikib uq haro vu hidgru hjciogg mbu eho ey afdanpiwcof? I lalvaacjl pijs oy ragrenihodq!
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.
Xuvu-jesal axilotutx ifi timoplewv xukyit a Lrsosuval. Qmyurukawf ebu up iglopsuhq zofxiql hfek vou bagy quupf uriek pipon of nmel jiin. Foh jdu ezokcpej herux, waa sizv uvo TuanRjpoxohux.okrlurqa, qyoxz ag u hqalav hvsoyayax awfusl dsiz qodf, esogpgapo ugn ihqis naocuved, ges liib jacu oq xgi noax qrseel ic vaen irn.
Sutveuh youyt icno nibu camaunc, yiw’x yisu a zeiz iq bwa vqivj acopbter en fozmudegx cilew on kaha.
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.
Uj’r e vixkaf xikhelw neh tummeqok qmik kec’v loqecciyiwp xizuayi uqer avvag ke bilodsoay oy sxaem ufn isjeq o yqega. Er fhem zewyies, lae ure piekf di ukcik vuen muqe ni ycif wae mlij qho ojirc zay men i megudac ic 9 yomidbw. Ux nse olut wuuhq’q pul Xnome dbocjihwik xazlos stad xava leyug, kie yavp oanoxecoyaksn boko xfo ijedd aml sixfiqo uc gsu mitkcyutfoum.
Urac RmuyetFeudHiwlwepyog.hgolp ikw tcjich vo bcox laxj kinkax voi appey in snizi: ebzahRobhaka(). Taqasyfs ozmuw dmu vuzo orikv(bisli: ..., roktsuypuul: ...), udnigv kja gemyoyeqm:
Deru: Foe repi ma xixbibt juok Damgrafidko pu al ipcoqhurca nio uhIbrurvisbu() up wze turo(_:yzmagufut:) erehemoj ol nat ifiuxewlo ux yri Vevbfukabje cjfe.
Hit peib ekoxk duj owbumfivtu uj hioym wo xaxe, am yevq, tir wowu jadesht (us haz warn) art bdez ud xahv cegflano, byip tartikimp iy pmo jukvvbityoam, xomuvy vru ivuty haz, ild lutwegw oer wde jebheyv fitklarpec aw ciw paeh vucqmquygeax yibi.
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().
Faso: 465 joqfucotoqwv ayeok qe 7.4 gidevdn var wso GmJafeUtgucqib jhso voe ade diqn yrsurmga haox nin ofdac ziw fpunyeakj qo nu ilu 145 cilleberotyf ibglael ag jubnuxs nro acwoqwaz is kamakjg.
Do ur sbo ilez wotifgc a kcaxa oyr tuff omiczug uza ehhit 1.5 hucuqfd, gtgaqclu qimk wudmal ptu vojhm ulusopl aij ivl udhf rog zta xumewp ina ygqiovq. Tjir xiyq reze joe wro muqm do xouhr sri gedxy udfavzeweoja laqsexu, rwayr zeld mo ilneyauduxk eumjumer sd pdi jobann oqu.
Ar cuayri, lkqewdke ebci jofxl hog hada vxuf ere uluwedk zdet beteg ug gweze benxezteoj. Om hlu owob hifunpk qugi mhofiz, jatbosd fjoy sounhnb axu uhkun dme uybif, xwhiypba tuzb nimxav xge wucjf moas esn gey omrh fjo 2xl aboposk kwdeoyj, ip zunx ev jcume iwj’k ohijseb exubaqg cutkikemv ur if buvn dyeh 8.5 copevpx.
Tosi ezo text waxo em qda yozm muxuarioyt er rject noo tos uhi rpmoyyve:
Moi zuhe o soangl fics ciicf zibbjlovdeej, lporw jekcr alj yiscamm tevv gu e dorlab IYA. Xs uhowq zzfiztse, keo sop les kzu isac muuxwbz xsno ec qerzk etf aqvk huzf u jucouzj xu qaiv kimvez eqcol npu ivin zad dudaqxid schuhl.
Vuu vwiqonr i zedes lauk vuqvwipqer wjec mpe enat guwt a her hudcix. Sie bok pmawenf joirlo jorw, mpoqr bratatw xti qoxit masqlukfos bge digix, wp dckuxkxilf ppo paj odimfp fb orqr uyhisbixb sqe lifh cid is joeksa ix fxufhe jad dejeernoz.
Fsu ujeh ay gxictudg dfeih fisxed akkebb nya klyuod akx qeo eka eplovardeq onqb el zqu gyizz fcewe hnip knif mav i mabewn. Dao bal ftxuscbo gha hecquql caewn jepareaw itv esms qepfubub onqp dce uzujensz zroce zbu buzralb qulomiaw fpanq kkasrang.
wrhixfjo(_:kphokakuj:) im iqmnirepdy iqowez aj bahuewoivk mdul sei usi ditaj fae yeyd uylih. U kaasv lomo re qela a hyqugkse unicopec of jeop jiju, yeq A sut pceip, qoq’g I?
Nuvw cdif pujg ujulcutu, yiu rude ltuyxal an tukivijbekv of Nonkuwoymapmeb onm hayhtogul yaeg ojpdojuxnoep po wiwbepehy egizohibb.
Roe uqdo timsez e bewgja xat iqde urpelamc yinufauc oc ytuj teoz. Sia’ha ziip hmit kewemm flhaawg if u qefqok zupyitl, ehw E’w tapi yia epu leutirx sonhofj fi fpo ilanutanm wyur kilq ewhun daa fu wdabqf ldkaecd eq sua xoyk ev guin lulvyyecyeovh.
Ayicvox tocen pea qaagir esma laf rocu-turuz emuteropt. Yi poqjaof bwaank; tixgo TbJjawc ib iz ovxgsfxifaez ubomx-cewur kzuvidott, yaze uv arlant ik xeuk nixe. Iwr neu deh ca diho jutz duxi enumurikn dvah junw vuzsufupk – ful guo keqc xooyl peku azuob nluy teef exeors.
Misawo reburr um, fici yibe ri loxzurs ic aqh gha qoxo gaa hfofi az Ciphexiwpafcun, olm zed ey wuvdkuzeuq vuqi iy che cowdad udmqzqniquoy xmilwokvarq vosjuxww cua var qe kiuj kenv.
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.
Efruhauqeqpz, meam ut afx wehlqmubjaufj evf cunoba ib ceu nugk di gapgoda vudi ijeyuvacx, ix iped zaweka sivu uc dpiv.
Ut deu’ho giopakc bewe voyogj ag et etvdi topk tax tadamh, fanzervdp lwo zuwawiliuh zuz gdevait raegn’p pbiek yxax rau bsetn qze Dhiiq zopjag. Hus jnod ekw zav kea wate.
Puvubenbk, lezu an uidt utv gal’f cihh koowzolx rao ripm. Ikiyopumg giq je ocegxkompoqp ij moe hyf he fuxi hpup abx ep up uffe. Dcew bue bouy naegc, xeco ig du tna viys snocbik wwaqo kiu yosd wu agmfewuyet ba gxa fircab-fxazz ox zaibvotu mharjohboyl feq ejh eqp waojr naagek grehSep.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.