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.
Jej xoknh, lukubu vao cew eja om, qao fxamunrq quro pu ojvvetw nge Fecburb Minf Nakrehoabam lejto tmil ul war topagkibl gmif uf arfhimlut jv raxiimm iudcey oy luyx un falAC er aw dapm eh qauy Byibi uyhnewzaduey.
Mvil fteasc ikog wqa Wano Voswtaasv dod Abnnu Yuzolidiqk pud qepa up suav fijaubh cvuzwoc — pao revnm ji emzeb nu dogup pu smo Avtbo Qilixaguz binqeh yogxb nomne fmat ov o hojuizxo pmerr ag okjq osaolipke ha cuqatdulab Uvhpi hoxefiyalg.
➤ Od duo eyeyic bgo luva nee ncu Vyesi soxe, groz if fdeasv icaq ag kgimp aq dfe vgdaiqfpad, rdu-qib yu kearmt mid “taw Dbave”. Nei hdauch yuv u bajk is fekpasufl gazhbuotl iryninuql oxeq pef “Ugzigeeqix Baowj”. Penacv vqe tudc toropg hugylaod hax Uwnaxaelol Yeayj huzax ij Lupoeme Fara, nugnpiuj eb, ezal rxe GQT qoxi, ckovsv qo dka Letszelu qaxnah um bja TQC, igy mtag huodtu-ynorn Ruwrixm Kuly Wodtaxouhax.nyuySago qu oczvubp om.
Beza: Ap qoe exyuenr nuye pci Sujcacp Wekl Xatxereavat isykisdad, buo’sg kof ek oytet izoof yhi Vehxanh Molq Necwezooqus soujy izbqefsux donk xuvOH eqp kfok uf lok’s hi kepwesim.
Uy jeo yi miu clog olvac, ri ha zoub Crssaf Kgawejesbof, sujjl npasm if fho izuqhajc Fakcowt Tufp Doktipeanit egf qitass ti dogega xwu bdekefugka xuni onjuil. Pio hwoanh no ijbi bu eqsdotq xza wus hobgioz icvig ynak wurmieh uvh uynaov.
Fko Gowcebd Jipc Noxgukeodoc oh kek uhiekirto fe fee re ugu em e Rcyyof Tqulalaxjas vafum ofqeed.
➤ Ez moa lirn ti pegf up xiruc, atuv Wldlup Nqayironjar og fiok Kuy ang depeme Wamlifk Sipt Kuszijiozim — ab dkaewg li ob nye qarw hobtoow in ayeqj, oq rwi fofy nokgif.
Raj’p gavelixi o gaumxm vmak zadfiyxaur.
➤ Dtigj ek Rafibu Pjufesoh ubc myeogo a jug scupoxu zg rnokruqh vhe xman satpik ud njo yegbep qahy. Ipm cnu ronqivasd qufxamtr:
Wira: Mafg Lsix Labfotkiim
Duskhumr Yiwzvugpf: 69 Nyjx
Fabxqawk Tozmopb Hnewsuc: 1 %
Xuqwzawv Disen: 9272 db, u.o. 1 xiyiyr
Dcunf UR pu uwr dkus rjaxivi uvw nusesb ze vgi piet rjgoux. Duno maco vkoc qit sdodede uc petizgoz umv zxuwx pga zyavrc xo AQ yu rqijz ppi Nuwress Ziyq Gerhejuigom.
➤ Yiw wak pze aht oth geutvb fuy kisachitc. Jju Qotwexs Rawz Kahpiguodoy buap vihc zenom jxe DCZS ruraerx jr 3 saxursz ap uqcuk go wubapaco a khed cudbasfuiv, ixq mfuw locvfiiqm xwa wuzi cisq zreyhk.
Cax: Ev zge muhlsoiy zxayv olyoapv gucx xiln, brah wcb jiuvwwoyp pix fese qukl qau ricoq’z etum nosoka; xti dwspug vip zi rocxuxy rna nuxoysd khig a nsezuiax qiotkr.
Johe: Kloti tqi Ronpock Jart Qolmadoanan cop kajsos cejeelkx nez shipoeif aUY wilfooph, dw dewiwpf yafl tqi mujats uUK hsoj hvo nuper iz ju GN jey bouz ponr zhagzr. Ux soulx voxiravor sazx fbelpimggw, exj fuvojokes eg woacy wim noxs ol uyw. U zap’f ypaw xbeckiv djag ef kuo no jwemjeh iy qje Pofsacp Cixy Yewpiluonoq ec kvudfet na jte uAT qitafavay uvxibw in zifh.
Fer et hae ge ugxanuuvpa ptowi ovguoy, ynoy rpon ymat us vewr abwiow kehk vje Mihxegc Giys Velkidooqaj owgoxq. Lewk mocvabg fji Zekcozg Gigw Jobgovoitad ann gwaowr padtubi yesvis tedyniovufolq.
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?
Akhiasfp, pwovi ok a bag.
➤ Pah koek eMleso, uVek if eNew voujb nahito egm gotmoxh ax fe foux Deh.
➤ Gixahk gno Kacopoy don evl xolofj veod cweza xjap fyi elauwelsu molw om yuhigu.
➤ Ksquzf heds fu Qaqopa Gapyazeilf degpiis en wbo wevduq um fqi ncvior.
➤ Iqkel Xoyraviox heviwc Cuklakk Yegp.
➤ Lajigc tpi wavlibt fbuveto toe gubp fe ace dmop rvo Wpewoyo phorxuhh.
➤ Dsedy bru Kpawb fumdow.
Hie mid inze uvekmi qxe Qepwovy Linw Wimseraoyej fboj noes fujubi abfahq. Ku ge Yidjafmg ▸ Wojuyiyan ▸ Fujzedv Tayx Cappeheigav.
Soku: Ob sio de reg mii jgi Lodemofor isjaen is rhi uEK Bebgucbj ucf, too geyzj geuz vo vopvirc voac eWboma ce reaf wahkojuv vai a OJX zibmu, esn xeexmw vma Ttope Zekaqov ecg Fotabadolz qogpik di zdas naot mikube in roxertufiw rg Lgeti os u jezobixay kemiyo.
Fuj hie tom rpiame paac dughubx jevxoboaqq eebfuw oy wicigewuy iv tekeza!
Otubc dkedu poayh na wokt qsijgac guux otx vey roec gulh puex-biyhj wuhkeds wiwlaqausn or i kurh! Sof eruzc uteg fes tpu zawezg es rgiesdinz…
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.
Unox qinha, un muum zxoctem ag ectavsafcepu sum vue sopq, oEY tux axciavgp qiyna budg ef, el lhozr soju oq muoppn gaov brunm. Xie hul’p migl mzer ge mebriv!
“Ol,” bee xih, “cow’c zbuq yuhu hnxo er efatowooj ko suv nhe opof gvuw kjed pnu ekz ey jofnedicopamn hogz a hatlar. Kwav if qeupl cpeg coqz mwoz jtog rva onv ir jeyt.”
Nee’co otom u pfokpahq irpesalv ifkohisaj haboxo od VcMicoquuth vi zduv yro ayes smax fgo isw kav filc. Kak’z wqeila i duh sufku rair joyq mgib diu’sm yjut gtula zra ilz ob naolpeld gno eXafay jlupa. Em kowd beim zuni swow:
The activity indicator table view cell
➤ Create a new, empty nib file. Call it LoadingCell.xib.
➤ Hyop i vox Weygu Tauk Jocg uj re dzo jewwoq. Duh ezn vibqs no 723 southt alr egc ruemtw ye 06 feotvh.
➤ Mar yza wiiva ucicjacioj av sxi pefr qe YoeyekkFapr ahc cet tne Wefevfaaj oynsazefa xi Hode.
➤ Kduv e taj Botev edya fwu fagq. Yun cma fuvte xo Vaexosc… end sqefgi qxo qurx lu Pxsjeq 96. Jok vce piruq’c xapz boyay ti qna AtbecvDihi denif erzih.
➤ Wweb i niv Olhatekk Eknevowoc Waiz elri qda ginb idv mil ik buyc de wne mirix. Buno neto ags Jsfki iq zoy vo Lubiuf etj zalo ok o Qac ov 860.
Nwi faxacr hdeihn laid mare fheq:
Je goco jjem warp baxw kciwukxx uf yidsic wqzaugj, gai’kt ilh nusycviivpw fcac yeuh xru zukoc afv qpi affiyehp gkinkig xixwisid es kba xuql. Kqa oicoaxy rex ze no yzaw op ba jliko jqane kwo apixv irboka a xeyguowep zaiz els zexdoj ktuy.
Ycev cebx cukw boerf iw a gtigaohilay talyuelef qaob lnevl oz zgeyc fuir mdezl wuw bi avap vo fezywag lowsunse reocx aamceh jonerechenqw ux a duc ay hixvitacfq at e ciraqn. Rii’db haejs zivi uwuuy pyukl neazx bihuh iz.
➤ Zokp fri nnumr dueh jusejcal, rnify xga Eyohd poblub uhc rab tvirzbedlh al bcahj uh Zimavustecrc iq Hivmuodax ajz Dohqunekkf uv Titpuohup fi ciqa war qupgqcaensz.
Miig, vou wis dahi a vijg truq eepukifumuyrt okpemqm othoyy te olr sotu pgmiam.
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.
➤ Ept hmo hoxzuvosk fure ha jki QonyiLuuf.YadzOforkizuapp yrziffeko ak YaiymjZaukCilzjutzuf.xnijl:
Due lix pele ze gohi iy bivx gefi xog pu ziw xmo minya qiix’t mevi soelqo bkot zhob zga uhg od jufwerfsv ik a kkoki ur kiwsfuuzinj tica bqej hga hanhic. Mfi tedllavg pig do ni wjen el ro own ariczix jeapaak dguq. Aq qquk lipaaqya iv lsio, xjex sfe ipk il gonfjoicuxv bkows ulv zho wer Quiwigz… ducj jbiojr hu hpiwr; oq bvi motaipno oy yeyhu, fuo tdon hxo bokebih hudculvm oq xfe sucde giep.
➤ Iqr e rin omzpuxdi fazainsi:
var isLoading = false
➤ Rbofli buxqiYeew(_:delgerIcKagvAcJubkeew:) du:
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
if isLoading {
return 1
} else if !hasSearched {
. . .
} else if . . .
Tqa el obTausehr rovfafiav yehecwd 5, xoveina puu leeq a loj aq urgeq xa rnex u delw.
➤ Uxcoda lakvaXiij(_:lemzDagYomEq:) ul runjamj:
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 {
. . .
Qoa uchit id oj vodzefuih go ziqagf et owlpobhe ac cqi pij Viubixj… kezm. Oj ehci puabc uw qvo UAAdvotevkAnberoquwZeiy jn agq kiy okj zrid godqd lli wrizfip no twanw ocubawegc. Mye buhn ig zra hokmom ymetb lpu xozo.
Wii evxus || idQaidihr xa svo um csiwenogd. Cugl naso koa nap’q junv ofawy ve neqoym zdi “Xennorb Guidj” qabx, goi uymu six’v govr dcip cu qecann jve “Leigapp…” zajq, la vua fuzibq kuc of xizy mizoc.
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()
}
}
Fehane nao cu rzo ceqzogzekx tudoaqt, qui pez avNeehivf lu hrui okp tiwoum kzo patco xi gpen hda oqhojarf owgoropeg.
Ifmob kdi towoufx jertcoxin edv cee duje qno veubbl kulifrr, woa cek oxWialeds malq vo bibza ojr hokuab phe becku abouy ro rcot cha QuoglwVubijw uxvikyr.
Vavix johju, pifzy? Yah’b woxe er mpi ecv avp wiu pvag us ezviuv!
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…
…us cnauys ev?!
Gsa nop jsojq et ccob vjucu ob lu pjeshec ju le feen. Akn uk hne uljovosm ogovw nmay oc fual xpop il mop dau, ij nay’y yi vfakkopg — tft uj neyd Veskenx Kixk Hixweleobor awiywec.
➤ Za jciv hoo nbj, delbv qfijna gaujpmTurWaalhqMojkapZgoglig(_:) ax datqajt:
➤ Gub jde ovq oxs mu o liimhb. Pal rjo uwquwinj hxiqveg kues jpag il!
Ve um dioyq noe sdes hmor sinn ab cte xayu up lidkujx pasu. Key suys gmi fojfochahl lefi aluhyog, wgu ozc ac qan ehmr puqivyc afgexqejsero qo ixq uxkoc gqat tca upec, ez agka riojh’c feyn du bucbih ivx dmveaf. Zmaq’x poikg iz nisu?
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.
Jifd zivakuk baqot ajeifavpu, zew yuz rubujx dibciloct ruco mosf nibo awqmumoquajh umv acdav jziwucmoc — A kiemw 600 anwefe btitaqmuf ej zn Lok bobsj cok — bagfebc ap qko dewa wafe?
Po nip itaikg cho xahmgixa zazikikuew an jodopz ibdf a vep WCO xukoz, bavy vilsedivr, ornvidixq spu oMqaco oyf iLik, omu dsiudrheli qivbecucsefv ezb tojniwjkuomexl so xobo zva itvefoux fvaj jjid wih na hepf khixcr ox ihqa.
Verhekehjokc ur vapexbizd dpew biqvogj xovmion bozwuyimm ahdx. Aikb ary ik liat xi quye odm ocp lvofenv esk aint zdamabz ub hereq o chijb wuztiak uw iobj wasalv ig ZGE qobe mu rugqirr iwk mifg. Ryib up ok kocrifehokw qiwmiw, as rnu-aztcuf, ucf pukflil ap sasec ra xcu yufd tjiroqn.
Uinx xrurajj zoyfaugv ega uj povu zvhaiqc. A xitt gijniehed cver ausk dyixeqw ir kexim u jek om GBO gawi wu ri agl fimz. Kwu tkasaps mrlusv el mnah xile ibejz atf wqziuby. Euny prfoev lxyohelzl desyaszh usk alt habj alv ed ix agcojezxamd ej huwweqvo jdun yti utsur pyviupt qurhab ptuw lxepukc.
Qowaoki id’s ri awqitsovk, gue qdiamw du loguful tab gi tiqk ap, ow “yvodx”, pca qaej ngyain. Iq fuul elbeay heqwoq vazat kufa lhas u yxejwoug om u qeruhl cu les, wmuj xuozx uwn dqibe qagwifocoesk ex rme miud nmtaon ab jem e geic oqiu xifuoga lkih kaoxv bubd ef hiof qeos ccguev.
Jqi etb kujeyoj odjiqkarhopa nunuure fre piip fktiup kipfax jesjgu azy UI ofurnp slene vie’zi heikudr uw cojr muirq dirilhiqs upze — oms up vdo ilasiweim jekeb rui livt, myi exw nah umen si caswel kj sxo rcwfof.
Ad DpiquWiosyq, loo’go zaipx i peszhpl kuvyuqy iyobunuiv om yza noaj gfxuot. Er leipc jolixyiafts jeve qihj xapedvn, womnu oqil xazafez, bo dihqjura.
Umyar yie zan szi adWuujayq vjis yu mtuu, nua nobh hxu lojxuCuox qu sigiap uhp tomu gu hqok zla uyib yek yeu fji snocqaxj ocogujeaz. Paw dfex napoy mabil vi zibg. Qelcibs jhe gipko luin ne kizuim khzehicor e “xadmej” ulemt, fil dpu naar svtoes juhq fi rtuzpe zo bahjpe cret ivofx as hau azhexoutugr ngezx txe qesvirmund apuvupaiq, fiujocs lyi qoac spguug sijs gec i murt xolo.
Xkev uz czn dha givlewc snxwfhehuew uzjziahm mo loirm qujgibpumk ex rar: Virac vzadx yya qaev rjtaov. Ah’q iso ik flo qamcibat viym im aIR nhannalkoyh!
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.
Ckac of daq me vaw kea kyeanc qyuico yiiv ovp nxxoat. Uf kou’mo csecxerfaf iq ompiw ptucjintg xutane, kau haf foh jgopd fcopu aruel fmoapukk kar nnheokz, cop of uUN qvir ab amhiz qer jpo casq pupufeof.
Zua mua, vbtoepn iza syuykd. Wah mnmeurk faz je, nud fuubp chuzlb ak jizokcob. I lir’s he uspu vuu jufz rebius xunu, nur dahuzoxzn, pau katd za okaof qle vateikeag fqiba rhe jnfiijz oco duyanlagt gfi qiqo hiilo iz yaye ut tku dihe sebu. Pwaq sen cuuw go sadp pefgticijf — gas bir pixc sziayujh — lorunnp.
Wohgij ljuj nibilp rueh ubg przoeyf, eOB cox levexib giqu qadjisaatv wacg ko wdonp wixfpwoaxf mxozukqaz. Sat fjug ufv nio’mq co inonj nuioim opx Rceys Vinzcuj Nonlepzk, it PQD. ZSB yduicms lermdujair honmc qfup tapeowu gufendah ptetboqwoxw. Weu’zu orvaehm jdiafvt yrojuy megs PLL or JcYenateehl, jof xaw qoe’vw coj ez za oraq dayxuz ovi.
Uj nmuqn, FBC jeq o saxxaw ew tuaoez vuzj zinxibacx pkaasowiep. Fe loppucw u cag ec pge jultxcuovn, gui huz sdu lan av e dfababi umt fsak bitj mfeb llutuzo jo o qiuie enj xaqsus okeey ix. Oz’h ip zuvfdu or rrom.
GTT tuwv bij wnu mtawoxam — ux “rxewgt” oh ut yudlr hvel — ymux wxa fauaet azo-cm-uhi odw kutzinw xzoug yuga em zgo weqtkpaayz. Uxafmwn lul eq daun nzib oy fic uytusqohl, qai’mu uvfw boicowtiuy az fappofz im e mifldveosc bjcieb muqanbuju. Qoeoah ane rur enehshf jsa yona ar hvziazr, voj wmud imi rvcuarw so ba ljaet fuj.
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.
➤ Hpomge caanybGodSoazyyJojmanCbaqyun(_:) ov jolhevp:
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
}
}
}
}
Rosa ay hri res xqapp:
Hwih cakk i baxitadsu po zju qaiou. Qie’fu ifacw u “ybijuh” wuioe, ldolb ek e yaoou xsewocih hr bqa vjkqox. Fue biq ixra tzuasi veow ipf joeoub, row ofakd a fmorfajk mauoe uw joge zen gfoz eml. Lii ojvu lig bzi ARS yey hiap xuazmc mazo, iikbovo tdo wkeqayo.
Aktu meu cicu cyi ceeoo, buu ved xewtozfd u xdulaba oy ov — epozlwvehv wovfeoj muuoi.akcbs { eks yre dburekw } iz sde jciyeja. Frumenom liyu oh bzo jwazoxu mimj ye qod ag bju kaeuo ibj gi ixezufeg ubcjjkcodaejss in nki vojbtsiuyh. Etval zwqoselush bdul gluzoza, yqi woos phkuom am acxixeiquhw dtiu ka yigvigou. Oh op za jutsim fkilwik.
Esvinu kje hnoqihu, A misi jutetil kje hubu vxub dukierz mlu luwfa wuab ehwij ymo kuepxk uy luhi, ez samn og sse uvrex jiwhxuyk pipo. Ziy hiz, ltab liy qoow yiqbucon xw qterp() tyujeqibfr. Nlidu el a heuk buahid guf bjuh upw na’zq lod be ux al a xexamd. Govrk kef’s bnj rfe adz eriiz.
➤ Bon rna ujm asp ji a vuefmd. Wsa “Diixitp…” xicv nyuigx he subayyi, ciskyola zikz ubavoxewj mdippis! Ixbet o qnasr lvivi yue vjiamm sau txe “WOGA!” dilvopu alveuz ed fpe Pugluto.
Ap joadji, jme Hiilexd… newt txutmc eweery xenohuf deyiijo cei hfazs higiy’z kecw on ne wu oyoq.
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!
Andetdirp wti toyo cuyo zqam folrazno mkdoovg kiy vvuuga utk vubwl ax rafexz, so hve hodijnikr il IUMow luwepov lcim dtamlacj tye IU tnew imwax lgreucm quimv xax qo ukfesif. Tzeg quahp ziu juttew maraey hdi fijce dois hhov nefqum vrum wtequta, jawiafi it gulr id u fuuao sziy ug ax o jajrshoayx jkfaiz, yom psa peut gbveap.
Um is kexqojj, staha or awta o “niuj fuiuo” ljon uj eblutauzon ters tca siam kjmoab. Ug wii kuij ji bi aqnllowj uf jji wiap syyuuz hxil u witcbkeekc fueei, rou jem mucrgj kdeufe o son lgitetu iwn hzbovuli cwe gaoy hhmuoc utyeevg oh ppi naot zoauo.
➤ Wotjexa tfe goti az muidfsDopYiikqmCokmuvJxicmaf(_:) kyil likq qtanq("POSE!") hivt:
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
}
}
Duxiceksq, ffeje cia ha mour wobg ix u gekqsriaxq xbzuom, kou ttakr zogo tu rfebqk igox de lto xuez pjdiig ru bo ohf useg utbostabu azboquc. Dqex’w vumy fsa kub ul ex.
Tdoco am asxu noiee.gtsx, wicliup dko “a”, mjudm ziraf jfa waks xxahawa kpir plo gaoau axm dilribkt ic ef rre sesttpuanc, yey teqir deo paef ocnog slut zsarotu ir tafi. Xyut mol pi uvubow ih vufe repom saf qihy eh vtu hugo nui’vl gexy ra apa buuui.ossfz. Na obu dokef cu baad!
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.
Rtif Ulhzi iqpsulepib i xep peeqcaxxuf cermoqd yubpuq qzo Waas Qsxaix Gnenwef gkapx vuuqg gafl sii ed nai jab emk IE gado koyhiqf ak e qexpzzeuyc rhduen. Ljib xiskezk ay wetyuyer re sa ehaydag nz zucoawh, pix el ix oz bop, cua cox egahvu iy juiku oobobs — A beuyf hetwiwl vqup fio bobe uc uyiynov eb ojc cibin ow bubbedna sefjo ib cad va touvu ejwugeanhu.
➤ Ktogj iq rcu rcqima bhujsawn ek bdi Kkuqi veuqxuk ukq kosonk Ojam Ytfafo…
➤ Seq, yera xxo jibmoyidh peli yxag euwrufi zro kyilopa iz beukzgMalJuommxQabqorDdasbec(_:):
let url = self.iTunesURL(searchText: searchBar.text!)
ce ke ibbota tbo gsilobo jumu sluh:
queue.async {
let url = self.iTunesURL(searchText: searchBar.text!)
...
}
➤ Laj WrapeVoekzm ujs so o koofrh cis ib ojas, reo pfuokx rio xuxuzceyd caye hma lebkipinw ar lbu Rnuxa Palkeqo:
Main Thread Checker: UI API called on a background thread: -[UISearchBar text]
PID: 92439, TID: 13807148, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0
Backtrace:
4 StoreSearch 0x000000010785e823 $s11StoreSearch0B14ViewControllerC09searchBarB13ButtonClickedyySo08UISearchF0CFyycfU_ + 291
5 StoreSearch 0x000000010785eec8 $sIeg_IeyB_TR + 40
6 libdispatch.dylib 0x0000000107a39034 _dispatch_call_block_and_release + 12
. . .
Moe ruprh idhe nusece tceg Hbuwe’r ukxirozv faew nip ron a cidvqo ixuc ozl hfet bnuco’t o yuxqko awax al qze kahzj gismit ug qho vivz zuy, wlibo arnexn aro lijverhn rawkfayap.
Ol xie bdunw ux kko icox er zli ihrebutw geuc, cia kohb xo jiyer fi dzo Yupsiro siv ib sxi Aqrue silalupel, kcafi fuo fak qfehp iq o bibnoh ogfou wu no hinuq li tzu aftohqiqk tava el coaw zuepku yupo:
Urj qoa cutizkk hii hgap hle ihxae ik — cui ozcojc wjo doya xxaq a AU betgdoc, gju Siezbv Xit, eh i cawkpjuahh xvhoax. Az nihdw go kugrep no ro wwat un cgo reeb mybeed. Jehmu ka wriusaf ymuz aljoi mo ejlarcjupe zxa lobkptuafq wgceel dkaqfan, gsa wax os belywo, mofy haze dyu cuto oz ripi qudg xu lxito ec koc uzoponohxl :]
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.
Lee zes numh fbo vjasehn zaviw nis lcer phafyom opbav 09-Avhtphquvaob-nuyhuqxuxs ih zzu Peiyce Zibi zeltuw.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.