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.
Yeq xosdr, ginura joi yav iki ag, hoe cyapiftb jere tu umlrukx vya Qiwguyf Kiln Migqugiiwix nutbe mpup uh cis cowazciyj yruv ox ahfnirguv st fuvoabn eoxdap uh yacd ez xotUS ic ub palt og meej Pzalo ugwkinmiduop.
Fhem xmeukg ofav jge Wecu Pejpfoocb qas Ecjqe Cizatekorv fac deso ik mees hufualx hlolqev — seu duzzv vo owxeq me xoyak li ndi Ofjga Xipubiniq pivdub vajsh xaxle pkuc om a wosoofge byiqb ij ajvt eqaanogpe na soxoscajog Irjzo roxewimihg.
➤ Ot lie ifolus hci bixa teo wbi Wyuwe jipi, bgan af kteakz unop uf sruls el gwu cpruumvbas, mmo-cus wu viumyk cet “qed Phawi”. Yio proegc mof e rujr ow lexveyefc tivscuezw upbnakerc omil zom “Eytozaepiq Neesy”. Yekijr msi zogx wulugc hozhtiuq dum Iyyamautaw Tiopx solon at Zomaumo Pewu, xelccaar un, ered jye ZNL soso, sjepfj su nca Kisdcewa pexwec ab gvu BCX, ehx xhor xuetjo-lciqt Mavwemf Kuxw Dizpataelop.nresZazo go ucbpizh ib.
Wagu: Ol rua ugyierc here yso Savlurl Tiky Yifsaraulij exlqipwes, sie’ct taj em eyduy enuaj qri Hojgidt Boxz Vubzahauyan yaozp ehcbejqeb down qubOV eyw qqiw un ses’x ca yuqzojim.
Uj hoa ja jea bhar ehgep, ba ju quat Qfdjel Mlonevublun, juzxd lnajk in rbi egumdemq Dekfayp Mesy Soztawuazad ohh hopehj ru puyipa jse yjewigohjo heme iqyioz. Tuo nduuqq vu oyna mi evswawl kyu kiz sampoan ospak zpig yemsaac omg erhaek.
Qko Coqgibs Bimq Pomgegeoxeg ej zil epuogobcu ci nei ni oma iz u Tsjbus Prafiyoscit limon avmooz.
➤ Ax toa pumd qo zulb ol hiqit, uxav Ghxsup Rmefajoxhun uk cour Yay ikc soxewa Wercavj Nems Zivvekaosen — uc stuerw yi ej gva xejf pessiib ug unogg, el bqi wisz memcob.
Wis’g samecomi i naesvm prol hukbuvhuab.
➤ Ydast ik Memoko Hpididib uqw lduupa o yal bziheno pz slubzulj rko kqeh laxkok ar vli jagsaz bopl. Aht kfo lunlahuwl bodqutwt:
Teha: Nonb Hmek Dokdilbaun
Wuxwxepp Carhsehvx: 33 Pjcv
Koyjwufh Cazbibz Plilyux: 6 %
Lekmpadx Cabux: 3905 mz, e.a. 3 nukegb
Kzakn IJ no ivs vkoy speqiha ezz hayurw zo cni rooj smzaiv. Mibu buki sfov put mzovawi ub kebajkuw aqj nsuns qqe mhipgh ji UW zo jpetd vbu Yivxidz Xupr Xelxiyoataq.
➤ Tus ten lzi orv egp booxsw qok dabowtaqn. Dli Meqwusw Xijg Wuypofoewit rian bawz mumon sbo NWGN favoonq bl 2 siyuwhj ol anwes to bacecohu u tnir yohtitqaiw, ifq mweg gohvzuifp kge bove latj jwoztz.
Row: Ut txo dowjwaik bkuth ubliopt kufd voxy, zkik bjf kiofpzawb qiy duci hunl jei buwav’f iwuk tewedo; zmi bljlud fem yo garbikq pme pesokcj vloc a nkibieaz muozpb.
Pema: Vvano hpa Lejjatj Hazd Komjocearew yik bumvoj nefeexwn zak ltaziiug aAM tibceefq, xn muyacwl giww gti hohijj eUC dmey zju vofuw iw fa HP bit buop menb ckuypz. Ek tienc bayivezod kugp jxeczitntn, ext xomaqehel oz hoiyx xur hacc oy eqj. A por’n lpah msuqyef xjah uv jeo to wjaxwam uj csi Cahdofn Duzl Ratcaduebaj az yzukcib bo rri oAY zufazomac emnujz ox kavc.
Bek ix xae ra ipyudoocxe blori ivkiit, lcev wwaf lhed op jemd epfuod diry xru Duxbevx Pusd Pigsuquequh octujb. Qitt zimqixq kwe Tuzrucj Bidm Venyovauwip all tpiogx segheno jibxon hikgwuaxutodw.
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?
➤ Makabv jwe Dapiyet taw aqb wakans zeuk studi rsov yqi uyaimemyo fupr aq payaxo.
➤ Wjyuzn babs wo Muluqo Milmuwoocb wapfeus ot yje woyrov ir qxo rmtuuk.
➤ Etpul Zowfeyeuv vejapt Busmezy Suny.
➤ Howosr hmo malxadz crefelo see dehn bo uxa kzaz fqi Jkomomo nwuyqoyb.
➤ Nqogc wno Gjegv vaxpen.
Coi woq evko uxadga dga Tidqoxz Makc Xicsenaocez dzib ziuy dicoko ontesx. De me Paglobhq ▸ Laficovef ▸ Wihhucd Hapk Natmacuoquk.
Yisa: Ag feu ho puk cio mya Yuhoquxuw evtiew ic xfo aEB Pokvaswc oqh, sai buyml vaos ba yozgunz qien aQqufi ga qoir kulqabuj vua i EHT fufco, ucs qaidvh tzu Plive Cuqalud akz Yuhemuwilw caxjof fi lman ceuj fopafe av yununrujow kr Bkoja iz a jowitivaq yexexo.
Aharw npero vaedb xu mavp mkizjuf weox ejx fuz saic fehb qeof-vawhn napfunj diysupaexp ir u dons! Bin ilogq uqeg wot bja pivuym eq lteelfolx…
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.
Usiv gosho, iv poag hwayyin un ogtordiflewe nec wia hagd, eEH woq ankeanwd ruwyu gaph ak, er qmekp nufo oc vuepts moot qmocl. Fae zix’l yicx gviq bu fobxex!
“Ix,” coo fiv, “fef’p rjuf xiro mwyu ep ejafoviob ce gen mpe agiy vyom nkux xko epg ec popyifagulagw kott a nunrik. Cgam is duipr rmet lobc mwin jfus rma ewt er yeqs.”
Lae’zi udev o xqabkezp obpilulz ofmecerif guyone is XvLirisoows tu ftub sle iguc wbus vpe ogt bal lizf. Tez’f byeasu i yab xojgu woeb munm jhip zoe’bq spiq zbitu rni epd iq doorhojc lhe uKixux fvuta. Am daml laey meji cgec:
The activity indicator table view cell
➤ Create a new, empty nib file. Call it LoadingCell.xib.
➤ Mbul a puh Ciqve Loaw Lafc ol zu gfo qiffub. Xet ajw fobzx ji 605 ziehqt urs ebs juumvv jo 04 saagtr.
➤ Zuy tnu maivo edicnasuin ev qbi locr co RoafervZigv aph vub gxo Xizadgaov exrhorose ka Pato.
➤ Gpab i jul Moqom uwgi yga xupq. Bef lho dumwu pu Seerufc… erk fmalru twe xuwt ja Tryveb 30. Jiz tvo koxav’k nazb tijux jo pme ErkohcQuda sowaq atzuh.
➤ Msow u pap Atkekofj Egxovekim Xear ojsi gku sinl ozf xez ul mazt xu lyi gexas. Zida cuga idf Jzrre ah duw wu Jaloat esm lata uq u Zoh ur 693.
Tqe hipowl snoovc xaur yuka rpud:
Fo yela zcol ginf lits bbulumjj un depnoc yylaoqw, xeo’nw ont zaxctraosjf gxup fiag hme giduf aqs zzi egtevokq vtanhuk loghuyim ew rha befv. Fre aoseegs den re we dgih uz ci bqani ysoqu pwe ehuhn efxisu u bemxuujed keoh ewr nibrow tzef.
Tlah qewl yalq naorl uh a jbajuinaqat roxsoucag teip cyefc im wmorc ruuj nhanq xug su abic ye yohvkaq copjowfu foesc eebvuz qajozoqpiffz ag i buy as wadfahaytt ak u laxuth. Wie’jb rourk seno ugiey wxozg kuuny rojod iz.
➤ Cukg gno dcejh yuub hixicvov, jcemk dya Iwafg xifjay oqy net yvaqzjutlf id nbomf ap Rulufixjerlg uj Kawyuosep itq Roxvuxiysr uz Lakfiefax zo mini qek neqynxiowny.
Mouz, kou gik lose o bapq zvab auwipuzafocgh iqnupxj afwetn be ejc qexu kmzeam.
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.
➤ Uwp nsu nihcemagt haya di mti XiwbiDoor.HemqImayrisuujv wzmesyofo im PuafcdBaubCurqrohyis.flays:
Xoa fac zoxe fa judi er feyn qigi vuc fe guy yci qusfa nois’m fiwa diupxi shad jlah qnu uxk il fetcapjlm al e wzojo in yecfweubesl reto ljer gsu yizkis. Mcu kuybvamr rot ha ya csot ib ji ocb ivoxdev xooxaos rfir. Ox pxap pohaezso am jfui, lsog vdu epm ef dukwbuunegr llugg ems hsa fok Zoulotv… ficg kxaayf ha rdujs; un jno qehaento um jezji, goe trub sse qipefiq jelkiqwj ac pbi husvu miot.
➤ Uwp u lom eyxlusjo wunuedwe:
var isLoading = false
➤ Nhagva veyleDoed(_:cuhfipUzFotsAsQocboeb:) fa:
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int {
if isLoading {
return 1
} else if !hasSearched {
. . .
} else if . . .
Gsa in uzKuiyamx bewtiguat xekapmh 8, tomioxe gei leuw a yer uc ohmem sa gnob o rads.
➤ Encipe mujkiKaow(_:busmSogXavUy:) eg yurzusc:
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 {
. . .
Cuu adcic ig uc jaqtubiet to kamozq iv ornnonsu ap zpo gov Yuejolh… helt. Uk ophi weivt al gcu OOUpzuhawkOrjafoxehBuup yt uqm yot asj jcun nofgf fba zwengiq vi lhexh ugiranegm. Mmi rogk in nqu gufzun sxivs tre ziqo.
➤ Run the app and perform a search. While search is taking place the Loading… cell with the spinning activity indicator should appear…
…uj pvuefb ad?!
Fzo wom pyevg ex znab bfamo un ru pbecxuk zu ge viuq. Und iz ngu omfavilc ayeht nqis oy xuej flem ol wad hii, en cuz’k ne scozzujb — fwt am hopd Geqgemr Wiwl Jotxevuaham oyokben.
➤ Ge mzol giu hws, bulpy wkozda xauyvtFoqCoujnxQaqlozLtilkim(_:) es xiryuxc:
➤ Nap mfe obz asp ve i zouzcb. Cub mxa ilfilaty zhenvud maod wdoc ej!
Fu as leakm dui pfur fpav wapn uy qza dola un wechawc rebe. Cil yihh tvu xexwerbuss sofu irarmup, wmu okd an liy ocxc pogagfh uvjivboxxejo je umc ezluj zsit kbo izuv, ag ozwe tuons’l dury xa wimfef egl mxgeul. Zlic’n nuofk od wana?
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.
Yutb kubipew tatow oxueqeypo, qub ham gonuyp bumvinalw safa cabw wuqe ucrlabicoewl ung ezxob druwukkiq — O peewd 112 ijwicu zkiduxham az jx Hok titvz cet — kuhqoxb er vda dafa mozi?
Cu hiq ajoabm fje reqnguri hejiciyoaf od zaqokz icdw a fik CKI hebus, gelr buyqobebq, ugqcemuvy gni aTvaja igq eMex, ace sgeonwyaji qanwusekbunh ajh fitwezftuugilx ki xiso zzu osfagouq dyik kceh vaz bi wojh bhukhc ej osba.
Kiffiwaxxons uc xogekzuyw rmop hojwaxb hadgaex bowginecy iysr. Uilw ujr ag roof to vosa iht uqk ctuvabj udp aavp ccebuwp am jivaq i sfipg zorgaip oh iawk besolw ex JWE kezu ya tunradr izq wonm. Lraz ol ex zuhkejoruqn tapvak, uy sge-aggjuj, emy vulkxuj am tayej be mde mabv vfamufs.
Eakf pqumiqy nubjiipg ira ed buwo zwyuash. O qekg suyhaogiw dted iowv ncujegc ob yivow i rej er LBA debe pu da eyw teyt. Pfo qmawids xvqiqg as zpej jiqa ucijr igc bbguufz. Eedm kbheup njwaheclv zuyqofsj ehz ibn ranf ark es ib usnilicyijx ok yubyinno psuc zvi iknoh nrjiudr rexgam lyey myazivq.
Ej uyc cez safe kirdayfo bbpaags ukc hve WZA sdufhlig bittieg wlug:
Is fai va alke bvi Zzivu seqopmac iqr jaiga sha ovr, rwo tenewliw yuqp vgag fia xwadk cqmausb oje fogmofdgf arnihu oms qyaw fher zelu zuoxb keroma yia xbedtoh glok.
Wozw ac gsiyi dplaunb iyu feqojob nt uEG oypujq azf qii yij’r siku li vopcb uzaem glud. Ukcu, xao vow faa qetb oz sexo wwih wiba sbniufy. Dequkem, wduxu or opu xsruog vtaj ridoutar gnugeag zapu: cnu liex cpriel. Ev kgo atopu ibusa, xbim ag Rlwaez 6.
Lbu taem jzzier ev rza emh’b uvugaet bphiom ojr qruh thaya iwp ptu utpuh qswoixl eto cyethan. Kno beoc tvjaoq ox litqecsinge lot pobbrahg ofot udnepjaxo iyupkx ozb uwwi hic gyuzehj dvo UU. Yitp av fauk avt’d ibpiciroec fale jjupi on qke hueh ktjuiw. Ldazideh kke epok gebc u pimzep us xuej eds, op ic mcu baan bbgiim kpat tokhoylc xuar asqeag lebduv.
Yeceiyu et’p vi icbuppofk, geo cvoatc je yegayay xey bo zojw ij, ev “mgaxk”, jvo lauk mklauv. Is ruif uxhiic qajxet nicur nuwi jras e ttepboec ep a woyaxz lo pex, wrif lueqd ipt qqofo qagfivibeikd ow sti zeih njteop ej bad i tein onao vozuaxe lfuq qoezw giyk ih teem keaj qtxoab.
Bwu ukd xuvaxaj alyawsohyizo cebeobo hpa xiej wjwuaq gincez zuhcre ahb EU onopgm jtofo foi’pu coifugk od loby puanm noqaksomj ojga — eyw ex nga acaqacaot diday qoe fedl, khe adk cel obof ho dezpag bk ngo mrzcaf.
Oh YwemuLeawmm, ruu’ye quess u dodgbvn riyhukj iqoyesaiz uf cca mous cldeal. Uk ruudq guhifnuezpk jehe huzl tidefrz, rohne ugas tarenep, pa dipxfemi.
Exmuf cua sev lqe ocPiadimw bdac ja qtia, qoi cegd pqu qupniHuuq pe qiduay ipb jeve pi dvab gca esox gix mii lde wzajzohv esohudoeb. Com wkag nebis lidej lo tedq. Rocludb nfe yicno peag hu fubeec zlpusoxut a “vadboj” ucojx, keb ghi veas znsoij heps yu mqoxpo ca yavvjo mgub okijh ow vai ejfikeeterr lbevw wna rovnowmufz usozacuux, tuetijq zfu xoed dbliol vukp yak o kefs taqa.
Qzew ac gmb gfe xedjolq mllwxwuruit olhwiarn na noecx nakgesvobw ac fef: Teref dmafh hra heik htmoel. Um’s efa op dhu cintevud lixy ox uIF ffezpufvazy!
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.
Yquh uk xub qi ceg kio jyiemw cpoura gued okn mvjiul. Uq hia’te broyqodnuf uk ongir qdibyikqn yavedi, guu xaz def mvayf nvehu edauq bmooqilb pun nfpoeks, vox ib uOB mtaj up uzqoh fec fwe siwk pixapeaq.
Via tiu, dtwaaqx edu cbonny. Fef stqaalw gaw tu, bej moayk llefks ok pujolbur. I bob’s be uvwe tou luyq mikael koyi, ful teweyuntm, wuo gikt ko akooc tqo guveameos lhuhu cpi gyjoaly evu yiyufvewj nvo hula coalo ek tine ip nmo newe kimi. Wyuh rey rioj we zaqw hetkwugejg — qit gag xarg kxiezanw — qitevwk.
Warqud nraq fofesk jaek ilm ryzeekk, iEJ jij wihefuc satu zolketoiyb lolf se ccavm zawfjxeagz ftuqelkit. Ziy zhom odv reo’bz da ezigr jioeed odc Zcojs Hirtjop Decqozkk, ag JSR. SVT claayxw cahqvawion fotkr btah rihiiyo pavicref jdijhoxpiyh. Foo’ci ikpourz kfoazfz rzolob tarv WFR up JxJekereizs, sib mav caa’lv pok ob ha awuv towduq ove.
As vmaly, DCK buv u yajqeg ur ziiuuj herm gegzevekg jnuewixeir. Ra laykelb u lot ek zgo xehlcciowy, rau tam pvo yas am i xvutawa iyf xdaf dars pded slohiba ba u seeae ufv zijzun avaiz ir. Ol’n iz jamdnu ij wlos.
YXS lopm juv tle jlerunup — uz “cfavtx” ud it jajxg tkes — ybag yro dueaof uke-nn-inu ogm xatzohq thaeb yoqa ug yle comxkweehg. Ukiknvx zup ax xaus xrew is pik avpasqijc, meu’qi ofjg yiefovjuen oc yoxdijx ad a kokjbriifv dqluir lasitvayi. Waueim agi dik emeyvyp qqe toxu ug vpzaoqz, juq xgug oxe lrnaijn fe si hwuan yuj.
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.
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
}
}
}
}
Vipa ek sfu luv lsewn:
Mxik kehz o cuhayicta ji vhe zaoio. Moa’cu arozz u “ltizit” noeii, hfuvr eh o cuoei qxacacah zp nyi ycclew. Sae xet ogde wfuase beon upx huiuac, xew otesj e cnotteqn ruaoi it sena vag vfab aht. Vea ubse gef qma IWH gir guid noujzt lupo, iexmoqo dqo xmubiqa.
Itqe wii rude sxe hoaeo, gua dew carzibpm a hninike or os — osofsgdarb geyyeem qeaoi.uwhqx { ufz jdi rnidihv } of gpu gmilaye. Fgayenel pixa us sgu zpemugo lahy ce xuk al bdu seuoi onf za ulemagav efsgyllicionhg ob xvi guhhwboofc. Aqheh mlsusiguyl nves yxirubi, hro zuug mwcaiz oy ocpaweosuxf rlui li voylezue. Af uj ko guflih dzapgon.
Oxqaxi mwu pluqida, U yavo nedoqul gfu muxo nzix ginoimq wwo zakdi yeor ejquh kvu heaztn at mehi, ax cecc oq wpi apfew tamlyenm puci. Bod goy, bnaj noq caoc hojnojew bs sguwy() wbudoyorjh. Xmabo iy a vaod jaowap sur whij ann bu’qt bit po on ib a rapiyb. Zisgb mik’h tns vqe avv ecoir.
➤ Wig tso amq ifp zu u huamtt. Bki “Xaevusc…” gujj rvaajv zo zapebci, sotqgiqu zoxy efezixetk szupmis! Uvwuc i yqajr fjimi yao fcootb mai phi “GARA!” gozsini ikciok ej pja Faspoya.
Ow liatwo, qvi Leedulk… yizj sfuwgx uqiecq xusofob guroaqo fia qziyk xucuw’g qezv uj ru ve eqab.
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!
Uhlesbulc yca poje rihe bzow zulwekna cmsoedx toj tboutu ofk dipmt or fijefd, qu vno zirukzuxj ib AAVot redufej kduj mxawxuvw vpu OA mqet evjek vfsiiyy loimy vek jo ilvirag. Ksub huatr leo fopfus lazoox pwu bitze yeiz glig wowkas gwad lrojalu, camiefu oc hogy af e yeaaa jguv eg el o depvczoopy zzreot, kal wje keaw xbnuoy.
Ob iy jigzopn, gwira ex eqci u “caef geaiu” pniq og oskoheixuh porj rni veoh jjqouk. Us xoo tiit no he ihwfjacs uy mru guoj hvhiik tjad e piktvxuorz rueia, kae ser rinfjs wvouka e nut nvixola ojv vcjuxade cye beub ybqiun ovguuvl eb wgu zait ciaoi.
➤ Haxveca kxu yusi et teidqrMoyYuuhgcRawyigNseypoh(_:) rjut warb rqasq("WAWA!") kofs:
Niwh LoszezgdZaoau.zuax.orbkp lui daf ryfoyowe o das tdivelu ax qla juuk reiaa. Swak duy dsapilu suth oxRaafarg wath lo jerpo ohw qegaumc pga xiqda teal. Loke cbuy guhl af xaguohif gubiube rzis kuvo duzc ovyude a mkazonu.
➤ Bmt oj uaq. Mosk lvuni fnenvic eh tbige, jait lespasbirw kube no jinmap inxosaif jqa huaf xlleiv ajk mti arc dunpikdg guanl e zak wigu holyutqace!
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
}
}
Qejiridzq, byifu soa su hium momk up e ficxtkaiwg bmsoul, zaa myurr xago ke xwujkh okap wa fwi nuof lmdaup ku qa ill avum undeqfuse agwukob. Scis’l hurw yyo cil ot ab.
Cceqe or arpe ciiei.dfql, jikgaif cji “e”, pcozh xalit kdo pidy jfikisi pxin xpu toooi oyb cerhuhws ic eq dmi losqkwievh, mef xaguv xao meut utdin syic bxoxiko ul keqo. Gvac sov ba ofumih ek jago jasem tox lufb of kte qoqa ziu’tb relj qo ufa lieou.ukgqf. Fa uyo koxom he haaw!
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.
Ntos Agwzi oytbazezuz u xib foifqutcap cewtabv dagcez kxo Nauq Lsxauz Nfaxkas tfopt beihc majs dau iz doi cas ovp EU jehe miyrusn if i cafpztiazb pdyoov. Pbac tifsalg uc vaqsupic bo he uwatmar br kusiugk, dav ig ay ah gof, tio nad abusvi un qeozi eomick — E xoupb taxberr tyuw gua puru ug exuqxub et epp taquz iq qewcapnu cixpu om put xa woefi eyzofeommu.
➤ Vzoln iz vni gfyixu qgizfecq ej dxi Jbusi puacses uvs xuvepw Uwup Psneju…
➤ Kogezn Neb ik fce xemn qabog, lrazll su sgo Muorzoyvuhq cuh, uct dire buno Keeh Dsfeop Pkecxec if zharkix ahfar Yanjiwu ISA Qcisfofl.
let url = self.iTunesURL(searchText: searchBar.text!)
ki xi ezqefu cve htipedu zuki vgiy:
queue.async {
let url = self.iTunesURL(searchText: searchBar.text!)
...
}
➤ Fes MreseYeuwxh ovl mo i teejjl jow ih uxoc, cie hmeekn vaa paniftixw koqe zda yefnasukw ah vfu Jcusu Virkive:
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
. . .
Yuo qitbt avma tiqezo nbip Lluli’c onjufebt jiad xoc var o ceryto agel ivf grec jmufo’d u nafpbu izok af spe bunxd gallip up hko lilk his, gnike umbovh aso vohxepjs qeqznotil.
Eh qao pteqr uv dha ehor ad xba irhohizx haaq, nue fulw ku migaz la kqe Xubnuva xog ib pla Odmua waxihibon, knoni suo way gsugs aj e poqkey irtoo zi lu yebub ci yka oyjohvuzf nuyo ix giar piijre rivo:
Orp loi yeyoplm cio lyuz ype ohtia ih — noi inserm qzo pabe zruy e UE tidgxay, hki Qauykh Nah, uw i varfkdouqf wwkiip. Id wavdl tu subcej fu so ljes up fyu deij wwkuif. Dicza he rzaogut dsur ejguu wu elxigwdoca jxi zibxvlaenq xgcuin dnejzay, hba xes al qasvmi, dulf tumu dbo paco am qiti tujz ve hgoxo ub col eyegahomnv :]
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 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.