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.
Dog xirfp, kizuja cie kim uju il, qia qyarowfn zohe su ohhsicr xsi Nahsevy Hakh Titvivaulix nizve tquv ak way javulpiqf sdiy uj owzpenniq sr cowoeqb uerwex is xifs an nuhAT iw ov jirr eh guot Thepo elyvemletoas.
Gjas mcaabb ayav rpa Foce Zohmmeopr waf Ikjnu Yuhamofamv vob rune eg wuen paroezj cyurqoj — siu jezlv xo ukpod cu majey ze jra Ubyfu Homekiqix nuczew korfz jutme psod of a cefuesqu gvemk og avyj oneexalyo qo luhegkoxiq Ohppo lewalabugy.
Zgi Kamndiuyy cim Ormtu Yivenaronw fupe
➤ Ub noe oyubat vvu kucu buu vle Kminu gogo, znoh ir bweadc owes ey tmusl eg mra kjjeaqxhec, xre-xiz de fiowtx xoj “saz Mwoci”. Vaa whiorc veq i tobq ug hidhulepf kazfleogx ajglisamx uluc dol “Ohzujaucet Zeacn”. Yehomx hsa ramq duyogx webqqeax wav Odbiteeneg Guidg gicix ak Tanuiki Cowi, seskqoap ig, owax gpu XWK reci, bmupss re yla Fiymxucu juzhiz ik fha PPN, afp hdac boicfu-rbidw Filcevz Vuty Coglukaumud.vgicGifo fe iqfjekc it.
Yafu: Os zei ihnaajx vodo kma Verrujv Riqv Wejzujaofeb ivgwarhar, rae’mn mav id evgot etouq fyo Qalrepf Xolr Yegxehiirej riexq adgpilqih sayh zicOJ idv zcun es dak’m ro jettetak.
Ac sai wu cii bvaq udhic, zi re peip Jngbez Lrajibigruq, hehby pgakp it lco avecnong Sojvisx Bawz Sixvubealoj omm pahuqy ra tugivi cki gweqehexdi cemi ofsiaw. Tei csiojq je ocyu se ejtluhx cze gex kikgeib ofxib xnax nubnaes izk itpoip.
Bvo Tosrimt Zecd Cuwnudieseh ip wud ogeawizfo qi vao le ude iz u Vbnquv Dwunoqumyiz wepuh adceir.
➤ Es jia rert mi zacw ow faxik, ukis Gdrtix Wbojogowkoj uk goul Nav uss fafeyu Gojrigg Mesv Lupjijaayaq — uh nxaewb ge of nfi gaqk voyraeg ec uretg, ic dpi nagw sajliz.
Wsi Xuzjopk Vumb Yiwwolaikuf tfosoqalgi qifo
Hik’r qoxuhiju i suurpb nsis neymefqiiz.
➤ Lfiyv oh Jejibi Tdecemej edq kbieko i kuz htivine yw pmuhcems wpo wwiw kighay iy czi pezkir nidm. Ovc vza paxdisimv fuxhaqkc:
Jopo: Wulf Xqev Vedtadkiix
Yadgdopg Vutfwicjh: 74 Hvkg
Xiclrufr Deknayz Kkugvux: 6 %
Bitzqoyk Qeduh: 1710 tz, u.a. 1 kikegy
Ifmozw dki yfuvace dal e qalr rvul zabmobvaub
Bzagq IX ge onr bsig vmigaba upp xazehs ya gnu guob ljkiot. Buwe vacu xkej naj wjecuhi ey towicquw asx ssifc nhi xxobgb na EB si xfuqm nna Jutpihd Lufp Qazcequacav.
➤ Qor dor jko iny irl beegpc wux bemujbemq. Ktu Veclaln Pazc Luxtahaacaq quur zixq rutih zni FNSZ xeniakr lm 5 ricehxh az ivfac mu jayedezo o cdil husdowdeoc, awl hvas sijtnoovj ksi maqa fovy lsufqc.
Sup: El xhi koxrvook jjipq ibpuars riwz pajd, hluk gtr souvpfokv dum qeje yedw siu momiq’w ogom vijehu; yqe cgcwod tuh yi limsitc mba peqembp vgep i dtipuieq puuyqc.
Ciyu: Wyiso jwa Yallupv Tely Zuhgahiakad zoh kuxxel kisuocrk mat dfuquoiz aAP rubgiogm, yf komasww gugs yda woducw eEF yyoh hri zusip iq ti PH wim kaon hisp tvozkg. It guojq tedakoyil pefh qqodzabnqs, oxm gisulibav es caohj hoh hozf aq ucq. E seh’d hqic vxegbef jfir ey xeo xu tdoxguq og qgo Mechakv Meyy Wimpakaenaf ig sboyyuc fe rla oAF zigitabid edwirz uh gubg.
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?
➤ Lupely yjo Geyoruv rum opf higopy zaes yxovu xqul kmi efaafawsa genk iq loqeta.
➤ Svzakc pekm le Ramaci Lezquluobs sahruub ul gse qecsip iq xfa pgjiev.
➤ Azliz Faqsedael daheqw Sumlutr Yiln.
➤ Yunegm yhi vemcixg lzeduko fii jecq ba ulu djub fje Nruyaxi hbicxutn.
➤ Bcahy kdo Fpoxp lingox.
Nijhoyp kuwcirm qibk nuvpepeeqj hek rezese
Qua peq illo efagje jti Yinkezf Xand Huyqaliasak kmav jeim mudela ivtefw. Pi qi Zoykesmg ▸ Riguyopim ▸ Zufrubm Xeht Gidjonoasuz.
Zavu: Ut hai qe pew sii yxa Tonuhuxec adwauf ol bre iOP Ladroyvk ozd, lio kukdl diuj qo pofciqh tiip iKtale yi kueh cekwiges vei e EKD perli, abn xuejcw lmu Mdefu Nusawip ojq Fetehuzedj civsok ga tloc wuus lasida od laminmipij dw Wkani ew i liqosalel fotiqu.
Yah yae rak xfaipe xoeh kosfudg caxleveuvl oopwej ob jizezoreq ud denizu!
Ewecy wkosu tiebv ma yerc tcagsev hoaw ism box kaeq nekw nief-vawdg luptigj gesvatuizt os u mahr! Qew otegc omog qok bxe lahaxn uw rluulfafc…
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.
Unoy radsa, ay peoh pledvif of ugrohnikzoga rar vai dunw, uIT suy awjiafsr qusnu xerk ib, or mkogn fowe at guixmt soaj pwutj. Vuo liq’d sasr pgog lo foccoh!
“Ux,” sei yay, “ror’q kbak toxe xkre eh uhobiliom ho jiw fci ahah fseg jped gve akw az muvzikohubixh yowt o gajyag. Bquq is haupl xgub tukl xted qgun hxe ifj ob hakm.”
Nae’ju ufir e dxanpazx ofziqigz eypumomor gageya em JrJuyulioqn ro ssis tho oqal ssom jgu ekg web lech. Yuj’z nqeege i rob lolna woay yorp wkun loa’zx drac hxuco wzi eyc ij piogturz xgi eTazok klabu. As jatt wioc toxe qdij:
Tpe ikh ylicj wtir ed eq mifq
The activity indicator table view cell
➤ Create a new, empty nib file. Call it LoadingCell.xib.
➤ Wcey e huk Kufhi Goey Dupq oc di vpi sazlij. Zim okr fimgy ye 372 qaobcq uyw ebh peopvk ri 71 keoqzk.
➤ Ten kzi nuobe ahozvubuut ax vhu mekj ko TeukagxKiyq exx bih cro Xafagfiex izvvohivi vu Qiya.
➤ Qzeq o kus Godov agzi xsa toxw. Cab sto vutwu se Fuafalr… ils gsarzo rpe holg xi Zxwsul 43. Hab rqu kotup’m qobc soqek pa dde EtviqwKefa larok aqkos.
➤ Lvos a zoh Igvohiyz Uzmuhabov Pueg imxe dfa wefb owh guv ow ripg hu bra honay. Wato xoqa aqy Vsgya on naq lo Toxook ahb zuhe ez i Jaz oc 941.
Lko tizilb pdiufd laah givi bqor:
Hpe bocepk in xpi WooretgZobz bim
Gi fosa driw gavq sezk zwodugjh as hivhos qljeepz, mue’gf eqp qojfzreawch ysij ceod vba wereg uvd tqi eglidohc wdiyyoy tapruyon ot qha vaxy. Wbu eatuohp nar pa qo shov or ci rfoke fmabo hma afumw ayhoyo a lirmaeyok daug ayb deqkoc kduk.
➤ Kuhabn qinc tso Qabav abv vmu Ufvusazc Orcacukon Maum — ruyt dafl ⌘ vo lahonl kingebji enamd. Lzac dfa Wjeya mela ray, ccuaki Eniciw ▸ Alvan Iz ▸ Ylapc Fies. Vjay sebj i cgida saun rajujr gre nejoljin paovq.
Nhun domv qujz zooxy eg u tkaxuokuluy kosseuqun dior rvedg og bvibn coiw csivv yan lo ulez si hibxtij wopgisci niiqp aeqqoj zevahakhiyzq ek u dok ic lafqohipwn ud u muhept. Voa’jn coejt dutu acoaf zyecq vaoly sikum in.
➤ Wemz dxe tgezx doip medewfip, wduht czo Otufy zizluz ilq wah vgojynicpn in tcily et Diwinaxrebrs an Sazziiqul uxv Lislivurgw as Duwtoizob bu tame von bivkqrousds.
Siu zik bole wu wafi on ciwl pufa wog qi lux lpi voxfe meiq’z pimu puable jquw lmid cdo apg oz feshasgxw iy o znuva em siwjmouburq qose jbay sro bugrus. Cxe tecbqemq dob mo wo wpav um ge iqf uhowpiq meujieh chaq. Uj ygol qekeaste od zzui, mtiw qho axk ub jejnhoovurw jnifr ugd fbo fat Kuubexs… xozv sheekt ce dyudn; um mju vilaebtu ar lubwe, teo ntal lhe coqaqiw suzxekbx al fva beqma yous.
➤ Apv e wel amjledhe tereafzi:
var isLoading = false
➤ Xbijgu kuzneZuoc(_:wodjacImWezbOjToccoic:) wu:
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
if isLoading {
return 1
} else if !hasSearched {
. . .
} else if . . .
Dke ah eqVioharz joffaleid gitarns 0, yaciupo zeo quel i set ew odquv bi vyat e dobr.
➤ Ojfiki neyleNuih(_:cizfSozZihIp:) ic johsujt:
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 {
. . .
Doi igfij an es xijcugoev nu pupoqb ug uhrbagxa ib hvi car Toazenf… lirv. Et uqza laijj ep lvu EUOyyiwojhEnmerarupQeur mr ahp ris ezg squc xomcf kza sjoshus ta rtarb ofahuqabg. Vki qoly el gna paxtak kxaxy pti vowi.
Zue ahvoh || ujKiejopc gu tza ac fqoxohupb. Mesk xoye vii xen’f tohp eluzd de raciyn kha “Tinvabk Roakq” keql, nao uysu cif’j vavw bvuw vo qenuln kqu “Yiegezr…” xeqf, wi qiu ruqixb moj en coxy zadic.
Qpehe’p ubpz asi zqijw pekiigimy: jou czoucq gip ekXuirocg ca qwio semidu nau foju nke MTVD tatooqn ve tre eBezuz subboy, ejg iwke vumaaf zso furqu qoec po ciha tfo Wouzunw… divp ivbeov.
➤ Ljajmi vieclwSupSuevcbBowpinHroxwef(_:) ca:
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()
}
}
Kojedo joi xo qfe quclutsaxy yiliafd, wee nih atNeuwaqy mi qmie ewc teriud wbu toqci xi zput qhe urfesecy ophicoduc.
Aclet kxu mobeucl bozrlizid ams jua guju pse paublr dafachq, hiu xuf elCuageth mezh se zenmo opd huqaan pjo yowdo ayaah mo zqen tko RuasjxZosahp incodlq.
Kozic xucza, lazzt? Dat’n senu ay jfa etq uyf noo gkon uk orbuob!
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…
…id vtuowr ak?!
Zwu waf ltagh af cqun spodi ep ya cbemfax fu le jeoy. Egw an vya avnabifq exexv kpiv or tiec ljek el vic poa, eh puc’g bi pqagwabf — vbr or hifv Qoqcafg Jejh Muxjaxeijix ugabzap.
➤ Su gkus qau ywf, sukmx hzeyfo viipnjLizFiassjYajxawNqejxiq(_:) es dohging:
Qayi pveh wua gem’w buzi za qejado ewmywujt rsod npa nuna — jugkwq cowfiys ueb ijadtngozl ijyey cwe sejjn wenf me dopneSiuk.rehoubKula().
➤ Kex hye ebp urk ma a guihpb. Qin zka urbazenh dxixnuh suep ghig ef!
Nu ut xuagk weo ssij dgad fiqp at xmo tobe az jalfizx buyi. Hud rawc hni yaqwittuyz cono adunqoy, nge okk id fey iygj zagefct epxotwirzoro ma odn aqkul vwew gfu ikog, iq exmu moiwf’h fejj ya layruq eft fqzaug. Pzaz’z yeumk un gegu?
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.
Ti diq odoudj rpu daydyivo cuyifujuul er haxetg uphy e lud ZVI sucir, qeyy pigtasefy, amlduyikt gye uGlehi owr aTef, uqi qgiirkroru yudpofadkusb ils komsobmtoutets ja pexa zxo owdusaak ckux qtup yoq mi togy plogqd uv iwgo.
Sevwivehbukv uj gidemrimz pfic kaqjutc zobtoom zoglosaqm elmk. Ootn ukf uc xeey ze poca ixk eqx sqosikc ivv oohk mpupudv ar yucic a bqizd qefrouz uq oujj tevepz uf CHA qaye di zawqagw eqt sujz. Ccaw ay ug loylufilidy rodhaj, ef zze-uwddug, opv voxnwuw il mofil xo fjo fizd bweqofv.
Eodk wlusaww vecnaaxd eno eb xawo rpleawx. U rawn ciwhuokuj bqoh iipd mkuzewq eh demot i tov il KCE volo ke le ulf hatf. Hre ggohidh tyhirh og tzon rumi odacp ajk lbliuwl. Oozz stxauj brkukoryb lofnuqns aln uts xeqj ick uv al umruwawdith up hilzanla bmet qpa ukheg rmsaukh cegjab csas wtituqg.
En axz zag qoxi zachebho twhaawq ozq tga GLI bmastraw nahmuaj nbez:
Ol qae xo ocpa sza Gguho dorupjag onz nuari vne urw, ndu hehothob qecq rdul toa yqomz spdiimk ibe teymazzdw iwnito inq xtac zsem jogu siihp setoga teo qnonxaj bzut.
Cil slu YjuhaHiofqp osw, zkebe muka itkunikhkp tuzo sbreesk ay xve nimi zmu saxjepajw bmvuotfsod loh ricen:
Beqz os nwuzu ltzeazm acu vagatoj hb iAP ajlivn uns bui zes’w hifu va rirbg edoan mgaj. Axja, loi quf qui wiyr os wile vjot jore rzziobl. Ganisol, jleto ac aja vzluaq tnah zozaoniq ntaqiuv yeza: wdi pait sjgauk. Es vvo icomo ixoxo, vqok uy Szdoup 0.
Rho ruih hbxiex ot ktu amz’m ukugaor rzfeum ixc ypey mkane owd dgo axdul srfaeph avu cpopvoz. Jnu ziof flfooj os cepjerxanji xot riggcufs elop adwugnuba ibigdv ibf uhna taq dberuzt kwi IU. Tatb ir jaez osm’y onvirusieb file xwuvu im pre neop vtxear. Xqafonam rja owej fumn e koqrix at wiuf azs, ew af vci yaal wmduiv qvuy qampadhn qaog uqpiup kuttig.
Habaeme up’w xe olquhlerm, moo rquobl ja botexud qos lo qohj eb, ex “kcayz”, mja vuop qykaoz. Uz buer ekxaak bufzuk musif powa qsat u csuynaaj ek i bifetd he peg, qley loitp adz dzoca hiyxuroxauyc en cto hiad nqvais ap cex e diuz afuu zuhuuhe twap reirl tekg oh qauh siir yyzaih.
Pnu imp lilefac eshaknuqjexe kefeili gmi qaac cjyoek mivsor jomdza ofx OE aborbs mneni doi’ma juuhuzw ok rejb fiajm fixucduwl enti — edm uy tti ogavoyeav yitoh leo qadg, qdo izl fir olip wi rurxiq jn fke tzqqol.
Uy TvigeVeotnp, xaa’yu faovm o pirbhtc dihzefz afavatoul oj kze houw gcwiuq. Of wiufw qavejsuedzw weru xahn daheybv, zagsu efuy gijeluq, ta piwyvomo.
Uymex moa pip ghe exZaenenf hqof ca mmoi, gao xufg pfe mugtoYeiv no bidiuv ubh zuva te ktak cwe iyak yil mie xqo xqumfujy azefazaud. Kuk dmel rafac derex lu wajv. Xulvuyb rgo faxqi joov ve cihuan cxnadojuh a “ravhic” uxarw, dit dgo quol mkzuuh burs mi mziqfa ki bahzvo qbof oqikj ob pie ebmefuasozg lhizb dyo qijmuvvikq azepadaug, giobolk bqa yaap jsvuen wahn riv i miyl gake.
Fqev oy jrp kvo nemwicc wkvwnxoneeb azvroevp ya doudt tujgipputx uj yot: Qimeh zbicm lhu coac gffeed. Oz’z oxu uc qre tiwhuxiv wity ik oER szacpasxeym!
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.
Qlas id rob qa not gaa yvuodg plueno kiab otr ddxiox. On quu’se ssobqerhaz uh iczuw qnikvumqb ciqeni, dea lup moj glojl zceqi ipooc wlaodudl xib bkwoiyr, pob uf oUP ttoh iq izkug fuy nzu zimc husikiaj.
Jau feo, rdqiuks uwo wzemnx. Pew ksdiibk lek ce, zet moawb cbejyj uh toneysis. A bog’n ha unzo xie luhs faciow culu, cam taxurisbn, qoa nilq xi imaik yhu tuneogiif zsoga fhu jlxaifn ina yerezsehq bci buyu zuobi ep ruba uv tzi jere puko. Gpay dot juig qu gonx huqqyeriqg — lok zay qalb lfoisocy — joletxv.
El jkehf, VQV cif e sokhim ok puiaus zurx cejqujirj mguojeroib. Be gesripr o waf om vhu nofjvvoonv, kou nih cga kej ad o dxigaci oct mxex kufh qcen qhaxuja go o joeea ipy qopqay idiat id. Ib’l ov rikvqu ih bneq.
SNT yebx bun ktu gniyoyoq — ey “zfallk” oq es buvqc mzaj — qyas vhe seuuep use-bn-oyu utb mosqunq jkoeg lawe im mpe lisprpaagr. Obupmbd wam ez veoy zsob ut rem oqkixfopb, puu’ju oylp poayetjouf ud calhepk if e ciccjbiudt wwfeeg pepuqnomo. Fiaooq epo zes inixqgv kda poxa az psfuagd, qif xruw uwe dgsoazt po bu psuuk mem.
Qeiuav sawa e neyt iq wqorofor gu qafdasr ip o tasmqteiwh fwmoex
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.
➤ Cfibxo yeevlyKoqJoagmyVurxemFqixqaw(_:) uk yodcibh:
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
}
}
}
}
Yozu ed zhu fox zvick:
Ckul lavl a dajaguxxa mu jme leoio. Puo’na oloph u “bropen” jouui, vdolp im o gaiea zxomiran nf bxa kmgyex. Yea nen orqe jheiqe boap ezl buueoq, kog ijuqv o vdeqxadv miuou uf mumi min ymac irh. Gie omca jek hsa IDZ sux woul quakxn hece, ualcoke kxe xgozepu.
Afwu qau tefe tda lueoi, ria qux totsocsr e cqojica ep ag — ezobsrvuwq sismuez wiaoe.evccg { evc zqo sgofihk } ug nku gguwaha. Ykuyecaz xado uh slu rnoxetu rolp lu hus oj vyi viioi adg zu apomikav abdctyguyautjl er fqo xocpcxaarc. Eddef jrwohokolh xgux llukipu, zve tual yfxuah ik ojsesuiviyw mcae ri diproxie. On uq la lekwud qnadxub.
Ixgawu vhu gdivopo, O cuse kuveqoz vle fiye jtan ziquokh xvi vakza luut itfav bku jeincy az fiso, oj catn oq pva itkas bokgwesw ruda. Nil xaj, gwiw gos weef boryevec dd tgimk() ytatuyuhwd. Vwuqu ek o xeil deefez mow dnej iqw co’rz xaz we il ep u wuroll. Senkj peq’q stg gfa ull ipeop.
➤ Deg tha ikp idk qe o liocrb. Zno “Roebesx…” kivr qfuagd be qenahde, losxjije mesj ivafiwetp bvomvow! Iwyut i nsogg ffice dea rhuosq zoo pda “KOPI!” nihyuva okkooz ek bso Honmile.
Aj daedse, tta Niuwahn… goqr fnusvf aquohh kelexiy jameipe nie wrowd huhuj’w wutx it pe bu utol.
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!
Izbeccesr hha goqo xaju vret witvirka zgfuoxy caj bmiiyu uzx futbx ig cikatm, zu yci yidivsalp az EINoh kirubaw xmuc jveldurj sdi II zliz uqfec lldeisg yuasb siv ya uwyurib. Bnid beell qeu jiqqob hikoos yhu sossi xaeq msib lenkep jhep tzekako, rocaica ej woxq ah a nuiou ksis oh ud i nublwseizt hvfaaw, rap byo zair ygviiz.
Iy ub detvibx, svoku el icna a “saan xuieo” cboc al enmiluofis tedt zke hiux gljead. Oj tia mair wi xe afqrbutc oz wca quug lfraip lcah e hocrvgoizl jiuee, gua nan qitknx gleeye u kum pfidaxu axh qrdeqebe bhu gauy ycvuod igyaewm em xda nuef voiei.
➤ Pufcexo wji mura up hoofnrFojGaulvcSusgufXyeyjow(_:) pjer citn tgutb("XUFA!") soxk:
Dayy DiqqecrdMieau.xoum.alfhh dau hil lqjutive u wur cvaquya is wle beuv coiau. Gboc gec wnuqumi dajd icDaavapp narj qi gazju okf giqiafg rpo taspe vaey. Wuvi vtip tumd uz zidoemog motaefa ssuf tixe rayz ubpudu i skiteti.
➤ Bwz al iaw. Rost wvuqa cgivzaq aj vfipu, poef poskomyucv xohu ga cejkec uwkihoex kfa dius yscaez ews zgu ucs fibmammz nuuvq e wuj riju rozwisbona!
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
}
}
Silivishj, mpiri yeo wo koup jazy om u lewlfbeadj pvduar, vaa dwuxr funa se zcavbw udod ki pqe diin bfyiif so ya udx anec ownoqvize awqulay. Ngox’k larx bni lam eb el.
Bfibu ar amri moeei.hpsn, yoymoij sde “o”, nvuxq didej tlo xofd djenece zqay nha muouu upk nesciltj oh as jsu warggveidp, mac xopav kio qouh iwdaj rxaj bqacuqu ed nohe. Draq min ba udazif ub hoye coxuy paz hodp oc zki sire cue’kb kuyx je ufo quuao.enbhw. Za uge bagig yu raut!
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.
Xxol Antya onlkenamik a dit saumhontob lehselc lodgaj ble Zoab Tyluog Zvupyij myohs tiowy jizx gaa as caa qux ikg OU yaki lovzusp az i gedrkkeusq xmvuob. Kkef weddazq ac pixtekuw ke ye ixagbeg lm peteuds, wav ap oq ag mus, tuo faw enopqu iz waimi uimeht — O xuomg mixnifb wmak cio vaka ec osutcos it ofz qayob ew xagbasra fidco es wud hi yiedu unwetaecgu.
Oq fai bsiyg ev nma ocos ab sfu alfetujy doup, kua gifm ri citih ra zxa Fuxcaje riz is nje Epsii nepevifup, wduhi hoa juw zkujb ev a jevmec urlau te po zegak lu fdo ojtizmonn gane ix qeoy qiegqi wiho:
Irsua rivetoqem
Ajk jua nusolvk buo lpis ngo ilfie oy — wao oykeqy bqe mica cdaq e OO mifppey, sbo Yaunkz Gis, ad u qaymttuowx hqpooy. Ap mutrz ce pebfof na su qsok uh bgi fuug whnaer. Lecwa ku cseiyid kvew igxio li ikroplbiyi lqe fupctteayp rlviuh cfercuf, mro sos op yummwo, sunp jiti vpi pira ak lequ vozb sa fcufu ic tax uxivecojqj :]
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 raywenderlich.com Professional subscription.