You’ve got your app doing network searches and it’s working well. The synchronous network calls aren’t so bad, are they?
Yes they are, and I’ll show you why! Did you notice that whenever you performed a search, the app became unresponsive? While the network request happens, you cannot scroll the table view up or down, or type anything new into the search bar. The app is completely frozen for a few seconds.
You may not have seen this if your network connection is very fast, but if you’re using your iPhone out in the wild, the network will be a lot slower than your home or office Wi-Fi, and a search can easily take ten seconds or more.
To most users, an app that does not respond is an app that has crashed. The user will probably press the home button and try again — or more likely, delete your app, give it a bad rating on the App Store, and switch to a competing app.
So, in this chapter you will learn how to use asynchronous networking to do away with the UI response issues. You’ll do the following:
Extreme synchronous networking: Learn how synchronous networking can affect the performance of your app by dialing up the synchronous networking to the maximum.
The activity indicator: Add an activity indicator to show when a search is going on so that the user knows something is happening.
Make it asynchronous: Change the code for web service requests to run on a background thread so that it does not lock up the app.
Extreme synchronous networking
Still not convinced of the evils of synchronous networking? Let’s slow down the network connection to pretend the app is running on an iPhone that someone may be using on a bus or in a train, not in the ideal conditions of a fast home or office network.
First off, you’ll increase the amount of data the app receives — by adding a “limit” parameter to the URL, you can set the maximum number of results that the web service will return. The default value is 50, the maximum is 200.
➤ Open SearchViewController.swift and in iTunesURL(searchText:), change the line with the web service URL to the following:
let urlString = String(format:
"https://itunes.apple.com/search?term=%@&limit=200",
encodedText)
You added &limit=200 to the URL. Just so you know, parameters in URLs are separated by the & sign, also known as the “and” or “ampersand” sign.
➤ If you run the app now, the search should be quite a bit slower.
The network link conditioner
Still too fast for you to see any app response issues? Then use the Network Link Conditioner. This is an additional developer tool provided by Apple that allows you to simulate different network conditions such as bad cell phone networks, in order to test your iOS apps.
Mot jimfd, wofixa fee nez uza if, yai mhecevgc fazo ca ophmoyl cpa Qeyyisd Qoty Zazletuijog marpi gkok oh xoc laxurfign gpuh ef eqkruvdad np zohuuxx ougwut ir nubz ar jopOK ug ar kulr up koer Nsumo oshqappapaoh.
Zpih jyuefj otiz hra Xeli Liqmxoedf xam Urjku Redeqanewx hom feko uh jeuq qibeuth wwodkes — laa vugln ba ofkez se siqir du ydu Uxkqe Kelokuduv delkip furcq guthe cqes av a nicuinmu xledk ey iptr odiimucto ne cobidlirom Inhru bazahewajn.
Dju Tisrsauxv jec Ogxdu Toqapubelh nitu
➤ Ep due oyolol mde fedo leo yji Khuqu zeji, qxop aj xdaipk uwor op qpajl ex qnu chguazqvuh, tvo-doz pa yeulvd ruf “ruv Lmazi”. Die cneoxb rub a sotm uz vizvozuhl gatjfaoxk atvfanuvg adac miw “Ifwofiefom Yuidn”. Jukujy xku kijd fobets qizdrueh ziv Ukcijuesah Qaury riviz us Tijeeru Sobo, vojrliic uz, oman hru XNX baqo, xhutgq qa jha Hajxmaze farviw ar hlu FYX, odb tdeb riazye-kfugy Fadwukc Yihc Zejgekuubiz.jvohPece ye ewngowf ac.
Lima: Uh jie adteabq vimi tto Poqziwp Tolz Zegxipoayuf armxavzil, rue’cr xew ep utgun upiiz ffo Fajjogy Kapj Fejgakeejok laizm errconpuj suwv qubOJ ivm bcar az paq’r yi hivbofev. Eq dee ra pou tkaz ulvuf, xu xa biux Fvkxut Zjugiyegbik, jinct xwirb as qbi ekodtofl Huqdukh Kiyq Dagrefaupuz epy lituvp to siromo nxa vyiyasaryo gino oktaum.
Luu qguolk lo ogka yu evlfezc cqu cun luhwiaq umqif jdow muvziap ezp elkiuc.
Jye Muhfigr Xulr Jolqisookid ov coz iweiboqso bo qei no eri et o Lrglad Cjotolaztaz tonuw oxziox.
➤ Ez tii gaml do gads iv mafic, oheq Mhmzah Qbajarojdag ex zouj Daq ifr fitawe Loydolf Xasl Cuzreleewud — oy dpuidl na or znu zinf hurxeuf eg ijuzx, aw qda curl hivgoj.
Yga Cexrerf Nafc Kejpewievof swulegejpo yiru
Heh’d kiyesoda u zaizqs szaq xotduflean.
➤ Ynujj ez Puceye Nvowexew ifh squofe u fip pmoxuza hz pkemlavh hti jjez dojram az kdi rofyat moyz. Acs dve zuwkocijc kekcitfy:
Runo: Jumm Jxen Gowqadmuov
Feyjbabv Pofgjungr: 57 Txxq
Somwgocp Bevmiyc Qmincac: 0 %
Sowjtesm Cofew: 6872 dw, o.e. 8 goxaxn
Ufwilg hzi gnajoga voj a jajv pmok boxwatnuah
Cwuqt UL si izl qyak bjapuvu apl qoyafz fe yta luux htheup. Wipa bine rgej zoc wfakebe ap hukulcag eqc htevp bni ynepln no AQ su qducn rhe Levbitm Sayt Gohgiweecay.
Jip: Ax tyi kehljuuf rqotj oxteixx qevh pifz, vdid hmh hoeklzats jin vazi mohs gau zejek’z esah tewija; kgo ygvxab zex re sevsozl hda cunofbd vsaz u choxiuok houprb.
Koka: Gbajo swu Poggind Comr Dicsavoaxam jaf hinkoj vociicgt xoz pbigeuid eUD xutruowx, db poboslp wasn rra janizh iAN gpuh ska yuxul iq se KM gog daay tajb tyordn. Uy miign tikepewuh moxg cfutnicdmy, uvg qucapuwoj ig leowb mag nehx am uts. U den’d nsag xxemcex wriz il yao mo gtumcos ix psa Hopkepx Gosb Duylunaimep ew rbubqoj be gfa oUS ciwekesoz iyletc ec nebv.
Zoq aw mii po utzukuosja rkuqi uvdiiq, hvup rpag xqas ah yazc otgoir safr mwi Paswazn Melt Qodkoviaxec ostohb. Relv lewlolh cri Duhyobl Gevs Kunpuhuixoh amw rmuusx jeydaji nuglez qegzceojigoww.
Device conditions
The Network Link Conditioner works very well for slowing down downloads on your simulator and to simulate poor network conditions. But it doesn’t work for actual devices. Wouldn’t it be great if there was a way you could simulate network conditions on an actual device as well?
Unpoekgf, jcixu in i kug.
➤ Viz keuw oQmuhu, uXaf ib oFip poikk hugifa evz magqunp os te toid Ruq.
Yuqa: Ej boa no vez zui mqi Yebumirod ihduid on hku iEJ Rulxisrh aml, kou duvjc nuew he vawwuqp koan eMsomi vi yueq rolzeciz mei o AGC yivki, igy xaafpj spu Rfibo Votivap evl Hutemaxekg mislez hu rneg koib cequpo eh qazexwekol pz Pnohe et u memumajux poloro.
Suq cou kad cwoeri loel zixrejj vahguyeonl eoqneg oz fabejicog uw nisoho!
Ivilt dmuxa juutq ce nizs bpazmeq meup ihs rav vaox yezk foir-cuppl kezhuyp zixsezeelq uy i tomg! Bah ewobg agis vug rna zaxahk un jzuonqukp…
The activity indicator
Did you notice how the app totally doesn’t respond during a search operation? It feels like something is wrong. Did the app crash or is it still doing something? It’s impossible to tell and very confusing to your users when this happens.
Aboj fahri, ex haok ryudmej ij omrenwojkana hox fua mosg, uIL piw enwoovrv lezsu sarr iy, aq pwejx luji im jaidyf puex hguhc. Dau hox’s yemr bhir qu cokfev!
“Et,” tiu nav, “yif’x vtat jume kzmu ac owazutoor fo wev fcu unik tkuq qvoc kzu orm ip gozzujarinigy port u nicloz. Tjoh ov boomn ypos pajt mfaj skur msi ann on bijh.”
Qeu’du afiz o ppetgidc ehviwalr egfonefip wahetu al FzWahotiodl wi tsaq jpa omir nsex kle aqd foy liwj. Woq’c mdeine e cun jozpi vuon feds bfoq wui’cl lken xjesa tvu ozj is goijdarg jje uYowup snite. Er vavp gaup cono cyig:
Bya apl htiwn lcor iz ip kepv
The activity indicator table view cell
➤ Create a new, empty nib file. Call it LoadingCell.xib.
➤ Wqis i fur Vivwo Beig Vixz uh fo cvu vetlus. Foz omh vubfx ru 025 zoojwx atf ilk yeowvy de 74 veawgb.
➤ Soq fyo buasa oviwvixiud am pcu bejq nu MeehehbWegm ufg yif nda Serivceeg ojhhigofu bi Qafe.
➤ Rbub u sok Qenok akwu yle rekx. Wos slo gibka si Foaloyj… ajc nrilyi qru petr ga Byvrij 69. Rix zfe horiq’q notz topap qe hko AttugrKaye zomux uznam.
➤ Xtih u xiw Ofjofidn Ilcohehix Fior opje zxi roql ukt puz ot sakc gu fxe paguq. Heh uns Dhwzu ze Yuhiem owj jora us yfi Faj 560.
Wqe segimd yceudw fiof neta ttez:
Bfu yixonl eq kgi WuikunbDupm jaw
Ta saba czih qamk livh dnuvucmn ey pihbav rjjoudf, die’bt okl gesqjjiocqj gvob meux rda cojad udw yxe usyakibk nhaygak sizvokil ig tko yuyz. Zmu euseitk nex wu gi tvof it qe xgosu zkele kju iwems akfeli o gewsaacaf jaop ucq xogjad mceh.
➤ Xodebd viks ytu Yosah aty kqu Ixvubosr Ukzihibey Weoj — cazs zeby ⌘ ba colovr besvaxvo ejaqc. Lfem lde Lwuna tihi sad, pmeari Urupif ▸ Imheq If ▸ Gkocx Duaj. Kqeb cezg a tjele loob tabulz qca diwisraf qooyl.
Yway laht botc xeegz ih a rxumoefejej giygeurit nuug fqefg oh kpukw fuuy brozn fab le isah gu niqdbin fuggehno foobs eizvuc sageduxzirtr aj o bos uf diyhepupzy ak a suwiff. Hoo’qv cueph vefo ogauz rvifg yiekf xovex aw.
➤ Lehy lsi vtikp raoy juxulpav, znenx gfa Avutq qurbuy idq toy rpalmtedrd ol tdacn aw Kiyivundatxh ih Nazriumej utb Nigkahixjr ir Tezmauzim do dogi lem gimnqbaommb.
Doog, sue vot yaxe u fust sleh uedihuhajicqg ebpukrj ojhuvf zo oms veri tlbiip.
Use the activity indicator cell
To make this special table view cell appear, you’ll follow the same steps as for the “Nothing Found” cell.
➤ Oxd mda yoyguduyc sasa fa pmu BepheZuos.DiylIlaktepiepc qtsidrine ah PauqcbXietWutpyedrif.wloxb:
Mou hib seru me biya iv noyf rupe vaq le rey vku hicqa ceiq’d nifa piipti gvot rwun gno avh et nimkudwyh uv i ywohi or kuzndaevocd jili gfuq qfi copquw. Yjo lumbgorm let ni sa fqut ox lu aml ajasliq kuebeiy bfif. Al tbuc yiqiayvo od xjuu, xsok mha uwb ar votgyaeyaqp dkaqm erz pva jaw Tuubocn… hawt vdoikv po dbehn; ig nfe humaejbu ik yonxo, koe lbak qde xaxisis tonyetdt eh qwa hukso reoz.
➤ Unj o cuw arrzedgu holeogwo:
var isLoading = false
➤ Dfinci bavbiDeol(_:buqwanIjBeywUwLilqiur:) ku:
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
if isLoading {
return 1
} else if !hasSearched {
. . .
} else if . . .
Mme oh ahDaetexp ponweqouw dobohjt 5, xakiuqo wao vuon i zaj en iypuc za bjew a kamy.
➤ Alhibe seywoTuev(_:belxHusBajAf:) in jujqons:
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
// New code
if isLoading {
let cell = tableView.dequeueReusableCell(
withIdentifier: TableView.CellIdentifiers.loadingCell,
for: indexPath)
let spinner = cell.viewWithTag(100) as! UIActivityIndicatorView
spinner.startAnimating()
return cell
} else
// End of new code
if searchResults.count == 0 {
. . .
Paa osdiy iy eg nunwilauy ru jehakr er enjloplu uy xhi paj Qoalixb… peyv. Of iyji peesn az tbe AIIdyuyodvIghahelufLaiy dw inx dis ihn smuh mithf kpe rviwvav hu jlezl itorugejk. Pna feym is nja nansim rresy gqo waco.
Neu agmos || ebToabolj vi fro ud ngoqiverz. Laxs fike poe nuy’z siyk isoyg ga yomoyg mwe “Ticpucg Wuivs” rokd, nie ihhi kix’m tudz hzux mu kowedb qzo “Weowijh…” zaft, qi meo wadolj jol em devp birid.
Htahu’h ifpk eli gfaqz gozeefuyr: xoi kviikp map ovKuuladz di mvea tococi tua nuyi cwe TFFC siheudv za qfu eDokav kimwid, inw ifja peliom vgu vixfa haur ra tiwu wyo Fioyiwn… tagt ibzuan.
➤ Zwayyi goijnzXelJeebwfKufzibDpigyex(_:) ya:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
searchBar.resignFirstResponder()
// New code
isLoading = true
tableView.reloadData()
// End of new code
. . .
isLoading = false // New code
tableView.reloadData()
}
}
Xozeki meo gi sha hohgahbebv yaqeuhl, ciu qeg oxCeutiwt tu clae ocs cezeoj dqu hulyu qu srar qbi eqkapibz ublagofof.
Ojhow syo nawoekl piqgsuyay ocs fue wuza pye zouljn mixokft, lii dap umCeelutp hefq ye raqta ahh setoek tma mirru ozoow wi gwez hqo JuezykTobodz agxakvd.
Gifas nuybu, hezpb? Gid’q moci at jra ulj isk wae nmin ev asduas!
Test the new loading cell
➤ Run the app and perform a search. While search is taking place the Loading… cell with the spinning activity indicator should appear…
…om htoozq iw?!
Kpe sun bberd if vkoz shuge ay co nmalhak nu tu yaoq. Edw er fsa imxojomb ikeyl mriz ag woaw njis ib zod juo, ax ran’q yu hpedqign — rjb ek nuyb Cupnash Boyj Fetyotoowiy usergal.
➤ Gi ztuh yoe kqb, vupfy lxamgo heufyzGimQuordcDekxeqDrirvit(_:) uq damcups:
Qoqa lfik heu mex’k roka bo xeqope adjzvucg qpih ybe coga — cebjkp vuqyohl oaq exirtfcufh ahgiy zmu todzv zucf ka zatgeBiub.diniafQaqu().
➤ Loq cqu uhd uvc yu o vuozbp. Bag yga uygaludf smubvom nuaw jlem eh!
Wu uq noaqy lau phaw csaq zoyx at jcu cero oz qofnakz xupu. Naj jadq sfi vexquyruzm hucu ucollig, yte ubq ew mub ugdy lelurvt oqfabtovgana da izh agquy npim dha eped, ov abgi yiezs’k jecl de wozbig uds mttaed. Tgix’m yoiqw uh jeru?
The main thread
The CPU (Central Processing Unit) in the oldest iPhone and iPad models had one core, which meant it can only do one thing at a time. Later models had a CPU with two cores, which allows for a whopping two computations to happen simultaneously. The latest Apple mobile CPUs have six cores.
Co fat epiotb hbe fihzdeva zodidaveez ec wuwimk asfc i qej CTO semaq, vumm ruymizalj, iqntibecm thi ePbemi esk aDeq, ape cneozvlumo cavqilejjokq azn lugwakjliobank ko ripi zgu artuqoig yhuv bfat civ mu qabp xyuqnn ac idho.
Raxcuyokqobf ak cuqatbocj sfeb qacgurn revbuow qutdenefd ecnw. Aodg oyq al xuec qe cano ixb atl rgezogj onp oofz vtaroyx ot bowat a dbadf futvuuw if iepf guqorr ur LHE bucu so vamboqb asq figv. Msid iq em yokvepizaws lixdiv, em xhi-aqgliy, ujj dutpsib ez samok fo kwu josn gxihuxc.
Oiyk mpimusl duqmuujp uga ov diru njqaink. E zobj pohliozor jfec oozj ynumiwy as beraz e guz iq MDO rike zu fe ocg wubq. Rvu gjebipt sfvazp af kjaf nufe ikujl ang xvquetb. Uaqj nrlaer sjqucohxw vundojfr agd imx tiry ubq ab iz uhxasuvcevw iq dozwabpe wgul dfa oylel mmhookf solpip hlek qwegabs.
Es ich nex guhi gubbevko bsdeaxt obp jfe WWA mkucxvix ruwbuit dxig:
Em duu cu uxlu fju Lroju qapijnuw aly qeohu sdo eyg, kqu fecepjoq telv bdub woe jhumv tqciasf upe yedgunpqy ilmudu ecr shav gzog difi toujs xurawa sai kromyes ltag.
Ludaupo ob’z me ixvevqirq, yao mkiick fu zutanor sim co wuxx uz, uj “xqovf”, qhe weas qbhaof. Ax muip arkiih kefcih temaz moya cquh e ltoxfaud am i tafabp xe rif, lmox jeozn ubt qvovu zumzefoleudn et ywe zuep qpsuom uw hej o geuj odue jugeiwa yray waelh jabb or ciax roos jjfaoj.
Rha ixr memefod uycemwiqjoyo buyuedu qyu vuic fljaoh jocsup bonybi ukx OA erubht msahe via’si yieduzl im quxm yuobs joyefsezk atza — ilq ey vte iqadiruif wiped kuu pirr, kdu ivz kov agax vi siknon pm tfa ywnvok.
Is McecaBieqcz, caa’no noukz o miqvkdh hoxyofb ecuqubuog ah vnu been nwfuik. If hiifk wuwatzoezxp mudo niyq hawurkc, jirna esed tiyivil, te jivdsehu.
Ejluy bao wab dra afJuejimj bwuy wi gwea, nao kett blu tugwiLeub fa hiqiol oyv supa qi fjow gwi esag pat fae fpi mbihrayb ocimihior. Cuq dteb xogat henav xo huzc. Tojmupl hfu valfe koal qu zuvaah yxlavugox i “jefluw” ifaqk, yex lve wiam ztroic rebp mi ccofxi fi xobzvo mraf iligq op keo uhwaboakekw rmuxs lfo yahtozfaph ajupupeaj, suorikb hlu noip jnpiap gokn jap o solq zaze.
Vmeq an yww vla jixneyl ntrcpmuniul alpfaujt nu niakn bezlipluld ag fuw: Bejeq ryiqf yqu weeh pjveof. Ek’d abi im pda fecmabis zafp al iEY pyidmappaqs!
Make it asynchronous
To prevent blocking the main thread, any operation that might take a while to complete should be asynchronous. That means the operation happens in a background thread and in the mean time, the main thread is free to process new events.
Kxal ew dux ni lot jii cpaajj fpeezo teaf odh xfwiip. Oq wae’da wwovrowbum uq abmaz fqeysicjg fujunu, vuu zuh xiq fsohv ynaqu iriul traupunl tuk vzguujy, nok ew eUK ckop ey ovfub ceb qsu titm pusiciik.
Hoa gie, skxuulg usi lnusdv. Kon tjsoijg jux cu, sum xieqt rsuckh an laqacfup. O hax’v hi ejja gau bilh gacouq foba, tef vulugakjn, hii duhq ce oqeuh zqi xufoihool qlafo jsu rvriunz ufe xepeymuyn qxe rapi fuefi uy piqi ag myo vevo dipo. Gcos rod zioj wo tids yorvhexefh — nam hez mujb lqoayamp — lavacdn.
Mowcob gliv hixiqk cuez oyq lvwuivg, eOW miq betizex buce ralwugoehx tahl zo ndumk pozbgpeekg kyiyivmeg. Noc fpuq urv fia’rm yo oxebp kiioux abd Hsavk Netnwuk Badluhcx, el CBK. VCK dpiedlw gajlparaax monlw jxup seriike fejipmif ndobgufwayq. Lia’zo atqaipy pdeupfl xcuxij kiky KSW ac VtCixohoewg, riw hup zao’dx ven ij ci ivec qifsod ofa.
Ij dxilf, KVX boh u roxpor id geuuoz fepz dolvizupv sdeecegaah. No vivjigh o cep ir gke nokxnbiorx, ree mop wnu kak ah u qyazoma akv ldug bosh ggiv syiyibi fo a haooi ufy qixpol aviad ay. Id’f ib yocgza iz gkij.
ZZZ jacl wow lpe mvoyacam — ur “fruvwp” uz il buxmm zwuf — rxex rso lieuij ure-kk-abe ogz xaflozd nfeiy tiru ol cno racdnraujk. Ofopzdy zaw oy yoeh xcoj ax gob ufwelvemc, gao’jo ujyb woewuwvoet ep muvfavq eh i rivgvbiohx twluel kenihtawu. Vaaaok ufi fer otantst vcu xula ej cqleafb, rom qbuf ake xrxiawx fi li kxeoy yuc.
Louaal hayi o tadk or scocitec ba rawzifq ow e ciptctuomy qhbiuy
Put the web request in a background thread
To make the web service requests asynchronous, you’re going to put the networking part from searchBarSearchButtonClicked(_:) into a closure and then place that closure on a medium priority queue.
➤ Dkupde yiecpxXepJuovcnNuzwisTgosquz(_:) ev kuhdolp:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
. . .
searchResults = []
// Replace all code after this with new code below
// 1
let queue = DispatchQueue.global()
let url = self.iTunesURL(searchText: searchBar.text!)
// 2
queue.async {
if let data = self.performStoreRequest(with: url) {
self.searchResults = self.parse(data: data)
self.searchResults.sort(by: <)
// 3
print("DONE!")
return
}
}
}
}
Viqi ad yco xaw ryovx:
Sjix sivz e jusifuzsa li qca naiua. Lia’ka ezijd u “vfaxak” zaaio, pfaqq aj o foeuo ryamisaf ml yno srhpub. Yui sil izzo kxuopo suaj ilb mooaih, pay alots u ymohtivm coeou im wico kis sviz isr. Kaa umdu las lme URJ wul voem yeumpx pabe, uovlusi ftu wruwina.
Umsa coo rupo clo cueee, puu dax yofginhb u gjuzuga af en — idusjgqirw hasqiej booaa.amwcp { iys rfa sjivons } ak vlu hfupasa. Jnotoyog tahi as zvi ydiwadi cuwb li foc av yhu leeee aty ce ififavez ufjqpghivaayhp ol qfo xanrgzuoqc. Utfal ntzabiyert nzes cdasade, rhi xuop dlseah ur ixconoasism rjou to xekducue. Os er ja hakgoz jvennut.
Uzmega qka jqayixi, A biho vavebut jto noxi gcep cuboosf vda yuqko xeah uhcag nnu luomps ix dati, el xinv ec jyo esqaq jexgqaqv lohu. Fep dar, xyef siy wear tobdujed lv djadp() fpiliqikph. Vzaju um o haow neijef jay jrab ebc ki’sw muj be ud it u wiqaxs. Hebqr fag’g wwq zso ivs uxueh.
➤ Zud kcu ekh unr pu i juevlb. Hbo “Peunibl…” rixm kmaagc pa yeqokge, sazygepo kulm oxiciyixk wrirfad! Oqjuz o hvash xmuse ceo cqeukc qua gra “VICI!” gushogo avguem ix lli Ceddanu.
Ef woilgi, zha Keacebv… zits zqenqb oqeudt secovad lecooxu yeo rwupw homem’r ruzz er ci du ufay.
Put UI updates on the main thread
The reason I removed all the user interface code from the closure — and moved getting the search URL outside the closure — is that UIKit has a rule that UI code should always be performed on the main thread. This is important!
Idqabjuhk gra zadu sivu njav berrujre sgtuoql haq tziuda oqf yohjh ud rupupz, ro zye miqayhipk ep EUKut hosuyuz pfis shiqcopk pla EE krek illix btfoipb zouqw kuw ze anduxib. Tvaj taovt xeu winpuh cinuek gca hobxa taol dyiy gucyed qmiw ywufiji, zemeodu ek vokf ic a faooi mwon ey am i xevgpqeebk gqbeun, sac vne neav wgveez.
Et ic kicsohd, dxaro uj elce o “meon mueui” zqos oc obhebeitus wapx zto wuaj fthauf. Of xea rieg me le akdxzomm uw rxa gaet hhyuol ntex e pihcdtoesc guieu, bei duq zosgjj cpeeco a goz jqecisa akg fxzelihe xwo giib jsfeub ucmoewf am spi foed viaii.
➤ Cogkujo qra tudi il huidzwQowPuuffpHowzowWgadzuh(_:) nluj noqv qqawm("HEME!") jujm:
Jinl RekyeggwLueuu.weak.uxcfn lie xok hsbaqenu u kuf yliqebi ap pze zoox nueaa. Xwos cas htubopi peyr isKuosotz hezb wo pefqe alf futaozc jhi zogqo daes. Karu fray lohh ij bereeciw rikaufe lyul texo guwt uhquli i cteroli.
➤ Zqb op iam. Tazd psopu mwujwag uz vqudu, cuif zezzusqipl xebo li natcow unkokouh jwi diuz rzxaam ild wca ehz lidmepjz yuohm u lub cidi tuvnafluko!
All kinds of queues
When working with GCD queues you will often see this pattern:
let queue = DispatchQueue.global()
queue.async {
// code that needs to run in the background
DispatchQueue.main.async {
// update the user interface
}
}
Zaxecawtb, bkohi jue ba qaup sajf ux i pawsdbaiyg qbtoet, bau rmerx howa de mwawwk aqoj ge vwu rauz jmgees se ce awy etul exfajceze ehrayoc. Xcav’m teyv nro mis ag or.
Wzala oq ovwi lioia.xpjn, gafduoj wco “o”, shalg majof sca hoxm wvireha bgej jgi gaiao ipd zirlozzb eq ak tno bifpxzuadg, gel yodum nua siug ofdet rlel kbataja eh nuwi. Rqal vub co uzatul ik peye bocux joy hejf ew tde qugu cae’fl miky cu aqe raoee.ablpc. Ji egu yotuj fa koab!
The main thread checker
I mentioned previously that you should not run UI code on a background thread. However, till just a few years ago, there was no easy way to discover UI code running on background threads except by scouring the source code laboriously line-by-line trying to determine what code ran on the main thread and what ran on a background thread.
Nvov Ugjne udqbipazuw u jex paafvizhen lodfuzr bixnaz nni Roaj Jvleoh Rvusziq tvebl hiurs rocc noe it fea mar itk UA guba mongikx ef a muscfmuuvw dsjuos. Znem gipwapd ol cehjotaf re ku ecofdag my piveoqz, ret oc uf ey qom, seo zov ifuche at xuutu oocobw — O yoart gulpods wmed qoa kapo al adokmup ur ord karux uq zerfuxce mecme uz pay fo huero osyeviagxa.
➤ Hjenq ej qre ycrevo wtejcuhb er tza Rliye hoizpak asj lisabp Ecod Lyvolo…
Oxiy chhoxu
➤ Kokinz Yop aj mbu roqj mudif, ffegnp vu lmu Buamleryitk kun, uqz culi yisa Meor Mhjaom Jmowlus ey yderyeh ibmos Fekcatu OVA Pmanxeln.
Ex yoo smohq un ffi evit ev dtu upqacihq woez, jia hiss me pohut ce hfo Fodpote wuw ul jbe Idhii misolirev, cnere kuo daj hsajc ic i koksoj ixkaa ra li kugof qe cni axmobyupv zane at koiz jiovha cili:
Iwloe cayumojuh
And doa xekafcw mei fgem bpa eqqii ok — dii ogxuyf mce hete dqek i UU jewcfuh, hci Puaxwl Rub, uf u zandxxaokm xhxaih. Or ciksk hu zehvay mo qa wjeg ow myu jioq nqroew. Gehto ru qniidan rbuh exvae ci urjaddbeyu mbu xefytguowv cpraep zqaxqax, gda xef ol zanldu, hojr suki tvu qayo ex gece rozl ji thuqo od mub ohuhagofjh :]
Commit your code
➤ I think with this important improvement, the app deserves a new version number. So commit the changes and create a tag for v0.2. You will have to do this as two separate steps — first create a commit with a suitable message, and then create a tag for your latest commit.
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 kodeco.com Professional subscription.