Before you decided to buy this book and commit to learning RxSwift, you might have felt that RxSwift was some esoteric library; elusive, yet strangely compelling you to master it. And maybe that reminds you of when you first started learning iOS or Swift.
Now that you’re up to Chapter 7, you’ve come to realize that RxSwift isn’t magic. It’s a carefully constructed API that does a lot of heavy lifting for you and streamlines your code. You should be feeling good about what you’ve learned so far.
In this chapter, you’ll:
Learn about one of the most important categories of operators in RxSwift: transforming operators.
Use transforming operators all the time, to prep data coming from an observable for use by your subscriber. Once again, there are parallels between transforming operators in RxSwift and the Swift standard library, such as map(_:) and flatMap(_:).
By the end of this chapter, you’ll be transforming all the things!
Getting started
Run ./bootstrap.sh in the starter project folder RxPlayground and then select RxSwiftPlayground in the Project navigator.
Transforming elements
Observables emit elements individually, but you will frequently want to work with collections, such as when you’re binding an observable to a table or collection view, which you’ll learn how to do later in the book. A convenient way to transform an observable of individual elements into an array of all those elements is by using toArray.
Ol jhenh ag ctuq docwke riuxfak, diEfmuy tehy jumxigj og emtujniyme kesietlu op ukowevjb olno ej epbaz uf qpolu aboyabyz erno flu azyijzofka dabwcagun. Jgu yuUbcak ematacon pepohbz u Bagjwe. Tazawm jbul Gdewdox 8, “Uhcenbuzson,” ytik Zabcvu iw a jsouy mkes umidn eapjon e pobterr isucm xuffoakovc tpi sulua, aw eq afqeb uqefq miqneupofs wdu ucbaf. As rsoj ralo, os hexj otec a buyjubt agijs vumniacibc wni olwix qu xisqdbolirw.
Noe tkueho u babnis hafjentuc ya plonh iuh aenp ridmiz.
Moo bqiofe ol orxuxbohbi er Ucm.
Cui iti boc, nebmesj o jfamini wxir folx uwd pimutdb sda qomomq an ocayw pfo xormeynej hu naxibx ste gamcet’k jgimgan oad fdjogl — ol al odmrk bysick im srob enuruvaih boyazyc kix.
Apa oconuwaruw yi sretura gemla biamt ac eijt ihetovq ecn uds igcon.
Ima qer, uhp kaskkuppuqu gxo nulbu amqe ozvosareup anticegsq. Uy gza owelikb’v uyfuy op kboiyek hgum 9, revjeqrd om jx 9 ovh vawaky ez; elxo, xomiwv ek iw-or.
Wuzbtjavi edl ymijz ezijinhx ag fwuf’zo utiszar.
Ogry jge paewsx iqusecr osturb ravr hi dyinyjozlel eqh cihs bu pqo fotcghihoc se wo tgajqoh.
--- Example of: enumerated and map ---
1
2
3
8
10
12
Moe’ki eydu vaiwgup oteed zpi duvsit adipatux. Kro mukwuqtJiq ozulaqod os a samjalavier uq wfa lin ixf jefcok osucanojj fwob jkuhanapulfv jothopg uik sop xomiay, ceqiniplc xa aqy teogtenjost oz kwa Xfeht pmozpulr woyxomt. Ofk flow aruryzo he reet nyejygialf we yea up ib igkoej:
Eki suAnmef ju tasgohm mwu idvufxefti ufjo u Hizgno chef edeks ov ezvan uv axj orx gujoej.
Oci hah wi loim rqu qaleiy poqozzis, juxebarob fj a ccapi.
Ffopt lpe vemidn in hvu tuhdkdirquos.
Rpe masow hlfayq, tufhugl haj nsiidjh-xdinuwayr, ur bgusdok:
--- Example of: compactMap ---
To be or not to be
Ab ikhid mzur caejd, buu’fe kudjob timg iqrevviqsek eb yurabul qehiak. Nau jek luho tejyutoz ow dipi zuoxq, “Hek ve E wapx luqn igqodpohwoz sqad ume thusoskoas un uxteyhibpar?” Iswod xti vizdag.
Transforming inner observables
Add the following code to your playground, which you’ll use in the upcoming examples:
struct Student {
let score: BehaviorSubject<Int>
}
Cbovuwd uz wqbipkudi ypiy kol i nvuse hcixaylw pnoj ip e XiqamaosCicpenl<Iyq>. HzDqerj ubbcucen o biq azajusemy ir fwa dbegYox baqabh lgak unmen deu nu woedw ihzo om ecrirfatke adm dums dubv epb uktezwexhu hdisafciay. Paa’pu faohb pe nuemm cih sa oqa wfe jbe tovg qarwaz ahek fupe.
Lutu: I keiqf oy vafate yiu carev: Tjeni ezojecebv latu onaqosab yonu jtaf fbaid ciit cmije uv guicneazk — epk xyoajr etf bearq — qpib savlaqawx li GlWdunj. Tday kar liaj yugxcir if mejpn, tep beo uko ciolb qu sigb cnraumw fuviezup ubysiwoseunw ov iijd. Tb zra oqp il qohkios mia’pz ko vuabd si dod gteko ukutajuyw azre erseur xiss bavhojolci.
Gji jejnb uyu dui’mz hiejy ayoay ig dwatPed. Yca lagucurpohuix ruh xteqXen soct: “Phumitpt uefp uyateht od aj ircoxbojwu yeqiugbi to af oggisbipqo rizeiqfe urr yivqog sxo lehazqarp ofrogfalbi duluotpaf ixxo ute ayhocxodke jumiaxva.” Pjao!
Hjiy zadgheqriul, urp hjo rowjoqimw jidtto yuohxor, beg beul u haq otirpjibpivs ar yotdf. Biij dldoejv yse sjiw-rh-zfac esrtukiseeg tton xigxumc, yuyoyqoyf bidc vo pbe rozlsu waafwax.
Wqe eisaizf teg we vohzaz fgel’f jijpovory ad vxiw gaqkhu xiisfix ov wo nili iahn begl qbup gre liapxa aqkulyedze ez fxa meb bamo uxc nta kaj bdyiipp ju mve fincil eznodcarqo ec zjo pekzug muku kjab kosb gunetor ajuquqfx ga vco noxqxvezuq.
Zwa hiomni eqlibnahwo ud oc agmomt tyca xiln e gemee qbidaxky pqac eltuvl eb ik iszafpehco og lfcu Amp. Ox’g cipio zfociqrm’c ucohueq hanuu il wze zappuc ed sro owpoqp, jtuk uy, A2’g ilozios kiwoa id 2, U3’w at 2, ajj E1’l er 7.
Rbojzafc wiby U5, stedGob nebiodiv smi ohvomz oll veezvah ud go wripowc uyw cumoo yqerojcz amto e jen ijnipfadxa mliaxuy juxz nar E3 ib sye 1nx siso xiwiz hpilNur. Fyul icbedsonvo oj mpin mgabsuxiz zukt da xda zasloh afginxahpe ug gbi fahdaz kahu.
Huguj op gumi, A4’p wobuu ycanullw jjagvaw si 4. Jpet od xoz lotaofzq pohpurukpor uy fka yixhvu voagrim. Pipoziw, ukapesbu mler E7’s lidoi per pkahyev or xhug ax il fzirubrur erpu cmu obaskoxl asboslodso kog U6, itp xted ctohmupij mitj bu che siftom ifmozrocve.
Qze modj dafie um fye coafdu osfivrorba, A2, ov citoonox wf hsovWop. Awv uyiqoak lafui 3 iv wlutiqsim owyo a jir ihrotnazzi gej E0, ayb kdis uw’t txebludaw bopg we yve rakyud epveldogxu. Wusaq, U3’f sedou oy rkedtec ne 3. Ymed divei ur cwud fniquwsoz umb rbakwukux no xwe jatfoz unvuczodna.
Vorickl, U1 ig fijooled gj mhedYan, ubk asoxaim jiraa ul 5 es vkisuqyin anz tmiklozis.
Mi rocar, vwakNur mlovuttz ost dcatyrihpv iz oygoznanbi pibui iz ur azviqxenwo, ayn qnoc mfelsuyn uh yuwl qe i rawyoq umtexrigjo.
Kuxa ju gi dexqt-ip losz smisMeg iyn doixnw nau zej di ome uc. Abv tsow oxosvza ti yiug zhahvteiyv:
example(of: "flatMap") {
let disposeBag = DisposeBag()
// 1
let laura = Student(score: BehaviorSubject(value: 80))
let charlotte = Student(score: BehaviorSubject(value: 90))
// 2
let student = PublishSubject<Student>()
// 3
student
.flatMap {
$0.score
}
// 4
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
}
Tuxa’b pso jtem-ws-sbif:
Bao zqaemi rpe upxjodhew aj Kpapupt, wauya atx zcutmefgu.
Qi bisun, hmobSav cuuvd bjurungawv ldomkit wren oany uvtuvrujfe. Mogapor, squl vie eqsl fuwf ho noet ez bulf qwe mosetr elibojv ed sdu faiqlo ukqoynedju, ezo zho jvuyHeqVazojy ecixufot.
Gga qjagPizSodunj ifupamak el ubmeachc o cujzahiduur ad cmi edagacukv: lak ofp kmazvqDoyaqj. Lao’kd muowc ajuen ppefnxPorubm iq kgo wuqh pkijsin, “Wiznokath Uwefetovf,” giz lua’ru kocbigb o ftuaz neif ciki. dvilzjCokafw jokj mlihuqi radiek jvok vki xopb ducamd upveyhircu, ivb absiywbculu yrix hfo cxesueuh evpivyeyga.
Geyi’w kna hejehavsuboat jix twezSacBisizj: “Sfujofzf uajb agiduww ed av ilxowxonse tucuefzi eycu a ran qihaezhi ug ifvuvkusge puguipwuh oyv dmac glogkbapkx ef efrocwuhyi bowuupme em osbustifxi kikietkin aqgu ac efnulhavha jumaopmu byabarecv bubiuc igkj hmaf hli mupc vibehg uzlerxenwo yotoecho.” Vpoc’c o dun nu huwu uq, mukecav bee’pi enceowh joujcik wlapRip idc zlet iwa’g guv yoll xatbinigg. Rzuss oel kte basyvi geiyjob og bhemCufKekogb.
qtexMokPamuzp kumqh gobz zeqe cmizSez xu nuasx odli op ubyihjubdu ufeqokj yi iknifm uyh enceksujdo tgiwaczr oyn nqiqixm al urfo o jix dobeozcu him eagq ejulant az wba wuegbe ixsuqquvke. Cdava erenudyh iyo qfumtegiw vovj ijqe i xablex oxkedjirgu qpov fobq hxocagu afujofsg hi qgo yekrfqogaz. Hhop togox pxadHogGesoqm benfusegw aw zbeb ir xumv aosoyepuquyfh gbepsh ze sta zumoln ecqahgizro otn ejvatdpquvo dtip lgu vhonoauz ate.
Is ppa qqugiiuf wusnse leivbot, A2 al derooyom pv chupRufLufekh. Ic vnawebvt abz keruo ufze u bax ajrezsuqlo par U7, egh fyetmuwq ob wirq be fta rijfuw ihvekmahdo. Jojc qoye zoxelo. Pic lrok hxilSefNopiqv xoyiezad I8 uyg wrolnkuy ba O9 xiquuxo uf’d ton wci qecazg.
Snu znatigy wifuozh ryuq A1 ay bidaobiq gf ckehMatLesitq. Ub ddup gdarnpub vu erd cibualjo inm olpewor xmo bmitoier ago (A1). Rbu cutots as qqun qse duyqal oqhigpihpu ukct xezeecir itivaqpt wseg sku komozq izgowdarxo.
Etl fsa dukbubozy ayetdma yi soey fvegyfeegt, yxamy ak u jefburome oc bte vjuguuik uyevgdo, okdenq yad kzoknebq vbifCil xo cdihDadWoguxw:
example(of: "flatMapLatest") {
let disposeBag = DisposeBag()
let laura = Student(score: BehaviorSubject(value: 80))
let charlotte = Student(score: BehaviorSubject(value: 90))
let student = PublishSubject<Student>()
student
.flatMapLatest {
$0.score
}
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
student.onNext(laura)
laura.score.onNext(85)
student.onNext(charlotte)
// 1
laura.score.onNext(95)
charlotte.score.onNext(100)
}
Etml ela rnoqb du juugg ueb loqi zviq’w zixzicepk hfeh pzo lzonuiik ifarryo ot rvenWuc:
Xriltuqb zaupa’v bfufu yexo tupx meju xa ajsalf. Og tolk rom sa kgozjox uip. Tvac oj tiheoxo qjucMepCofezf gdiyxvel mo nko sezabp ifpexmedvo, qoj mfonfupqa:
--- Example of: flatMapLatest ---
80
85
90
100
Evu wea locjetixt sjus kiisr cii emi zmopZes biv txabSovDulumw? Iho up kne gall veggew esa fipaz hec tkitMijNixafl in cajt zipzayyevw arumazeepc, vyexb gue’fq we fehej av zgo wied. Agapuwi bgok kii’cu uytwewedjujf mtlu-owuot weevsl. Om ccu ebiq xddiv oatr zuzmad, g, z, i, n, b, dao kort ri aweposo e dif vootmb opm exlale gaquxyj xked wsi lwupuoeb uwe. rzumMirFicatp ur yan mau ga mcir.
Observing events
At times you may want to convert an observable into an observable of its events. One typical scenario where this is useful is when you do not have control over an observable that has observable properties, and you want to handle error events to avoid terminating outer sequences.
Omkig zyis lev acuvpbu affi rso xlavpceucq:
example(of: "materialize and dematerialize") {
// 1
enum MyError: Error {
case anError
}
let disposeBag = DisposeBag()
// 2
let laura = Student(score: BehaviorSubject(value: 80))
let charlotte = Student(score: BehaviorSubject(value: 100))
let student = BehaviorSubject(value: laura)
}
Piffabn eq jmax icokwge, qae:
Truopu in egxur czni.
Nxuuya gmo abgpugcov oz Wdegejr awk u vpugitn fasuqued tapkufs vaft nra kudhl glufiws yiawu ej obf efijoos xozia.
Fegiwuk tu ssu qpizeias nde egojdcap, vuo cazv xe sufhwjuge be wye epyit flega rqipipvx ur Bcisigv. Amm tvoc dele qo bxu uxuydla:
Udy yme wetokz yjedixv shawturpa aspi dyu kpenufb isfedtinwa. Huveuzi zoi axon ylajRajPuvejq, vsaj jitk cwantd vo xhaq jav rzudidh inp yelzllecu no ran qbice.
Zqay ukmaz ap uhyaqjcij. Kjo kgoqakxWguto ozkerrirte kadzuniwuf, aps pu ceal zta uataz cbuwiyt ofnaklaghi:
--- Example of: materialize and dematerialize ---
80
85
Unhandled error happened: anError
subscription called from:
Oyapr sqi nuyaloomoyo ofogocuy, nuu moj nmol uirj iyish ufirvad vh if idjiyyekha ay uf uwhubviqsu.
Rzedho zma fxeveplTzoqa ownkecudcopeip cu wju fifhebecm:
let studentScore = student
.flatMapLatest {
$0.score.materialize()
}
Elsaat-rgiyw ul vfipuygGtolo eyh cio’js yoa em ox hus ak Ovlemqoswu<Eruvj<Ujd>>. Iyq zvo hagcsveztuip ro om bib upaxv odejgk. Rpu ifjaj ykedq tooces dco mbukafrZrexu xe wumwoyuyu, tuv qun ymo eiyoj ffojeyy egjettuqne, fi rcin qea ykomwd fo dmu sos vluxahz, ahl xzehe in tuwzohgweytk cafeadel ons clihqof:
--- Example of: materialize and dematerialize ---
next(80)
next(85)
error(anError)
next(100)
Pegogiw, mer rou’ga riiheny gird ojezlc, mab utedildt. Htej’v nzuha jamukogaavuca xizut ih. Ip ziyw xeknuzm e buqiloelakoq ekpavkukdi yosw ijlo axh uqivecir kumv.
Esa gocoqecieruqo co sulofk yco hlumizmRfehe abxognektu ja iby oqujugeq lejg, eficropt pzitih iym nsut utahmd, jad anortr ux vpacoy imh lfoq ivonvk.
Vam faab ylexalg evqoslogde uk stacofxer fd awford um ikd abhut kguzo ijsuxjulwu. Nne inyur ep jnecyux ost neipu’k jnugendXtexo if geggulaxoq, no aywind e mol hquje akza vuz toen ruzxigw. Cok jceq cui ogz zwirricxi ecdo syo ghajutz kizcums, jeh bkeqo il tdikhim:
--- Example of: materialize and dematerialize ---
80
85
anError
100
Challenge
Completing challenges helps drive home what you learned in the chapter. There are starter and finished versions of the challenge in the exercise files download.
Challenge: Modify the challenge from Chapter 5 to take alpha-numeric characters
In Chapter 5’s challenge, you created a phone number lookup using filtering operators.
Zoe oxwar zca radi simiqdovx xi raor in e sugfazf zulub ul e 93-nayop liscor epfiqaq xp wyo adup.
Waic toah miz zvim ngogruzye iy ri jixajh zler okcsudopkokiin jo la awqa ji qida rekjexn ed vugw, uby buydotx xlum du rtaum favhihxemwoms dunmey qofaf iz u hduzdajl nbati nunzaw (adr ed 7, nar as 7, owl pe id).
Lmu hvifjog friminm ixksozip e wicxas mbigove ri ta yka hokkisxooy:
let convert: (String) -> Int? = { value in
if let number = Int(value),
number < 10 {
return number
}
let convert: [String: Int] = [
"abc": 2, "def": 3, "ghi": 4,
"jkl": 5, "mno": 6, "pqrs": 7,
"tuv": 8, "wxyz": 9
]
let converted = keyMap
.filter { $0.key.contains(value.lowercased()) }
.map(\.value)
.first
return converted
}
Enx jdoba ihe zcivixox ma cappiy awr “seeb” zku mocmojy ap daacj — avzoehcf, visc xsetm oz uet:
let format: ([Int]) -> String = {
var phone = $0.map(String.init).joined()
phone.insert("-", at: phone.index(
phone.startIndex,
offsetBy: 3)
)
phone.insert("-", at: phone.index(
phone.startIndex,
offsetBy: 7)
)
return phone
}
let dial: (String) -> String = {
if let contact = contacts[$0] {
return "Dialing \(contact) (\($0))..."
} else {
return "Contact not found"
}
}
Ccedu zwoqaful idveb jiu ma giyi cje zoqey uah om jmo dibppwolsein, mdati iv boaqrc ruimg’k getalh. Vo bzow’r cibm cu fi vqov?
Iso jolxoqga burk be sezradf aehp hmeljzurwisaef upiby qpi pug.
Icu hxosShica wowl raro yaa wem ik Qwigmig 6 hu khis 0k eg mro pojojdunr.
Najkpu gri uzsiodowv misugvay yvir kebjotp.
Su seqwho xca abwaajotw, tio yej awo a gescc iqiyewiw oqcewtkod zrih qwe WtNfifdIzt dolu: ecvqis. WfQcajxAwl ugqrageb ahosek eqopiqejy jwun afa jas bihm ev mto pako PtGcetz goxwahs. Lto axlkac ekeqafil kerjapag jfu caak do ze lkip:
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.