So far, you’ve used the Data(contentsOf:) method to perform the search on the iTunes web service. That is great for simple apps, but there’s another way to do networking that is more powerful.
iOS itself comes with a number of different classes for doing networking, from low-level sockets stuff that is only interesting to really hardcore network programmers, to convenient classes such as URLSession.
In this chapter you’ll replace the existing networking code with the URLSession API. That is the API the pros use for building real apps, but don’t worry, it’s not more difficult than what you’ve done before — just more powerful.
You’ll cover the following items in this chapter:
Branch it: Creating Git branches for major code changes.
Put URLSession into action: Use the URLSession class for asynchronouys networking instead of downloading the contents of a URL directly.
Cancel operations: Canceling a running network request when a second network request is initiated.
Search different categories: Allow the user to select a specific iTunes Store category to search in instead of returning items from all categories.
Download the artwork: Download the images for search result items and display them as part of the search result listing.
Merge the branch: Merge your changes from your working Git branch back to your master branch.
Branching it
Whenever you make a big change to the code — such as replacing all the networking stuff with URLSession — there is a possibility that you’ll mess things up. That’s why it’s smart to create a Git branch first.
The Git repository contains a history of all the app’s code, but it can also contain this history along different paths.
You just finished the first version of the networking code and it works pretty well. Now you’re going to completely replace that with a — hopefully — better solution. In doing so, you may want to commit your progress at several points along the way.
What if it turns out that switching to URLSession wasn’t such a good idea after all? Then you’d have to restore the source code to a previous commit from before you started making those changes. In order to avoid this potential mess, you can make a branch instead.
Branches in action
Every time you’re about to add a new feature to your code or have a bug to fix, it’s a good idea to make a new branch and work on that. When you’re done and are satisfied that everything works as it should, merge your changes back into the master branch. Different people use different branching strategies but this is the general principle.
So far you have been committing your changes to the “master” branch. Now you’re going to make a new branch, let’s call it “urlsession,” and commit your changes to that. When you’re done with this new feature you will merge everything back into the master branch.
You can find the branches for your repository in the Source Control navigator:
The Source Control branch list
Note: In the above screenshot, there are multiple branches already — one branch for each chapter of the book. If you have not created any branches till now, you should only see the master branch at your end.
➤ Select master — or whatever is your current branch — from the branch list, and right-click on the branch name to get a context-menu with possible actions. Select Branch from “master”…:
The branch context-menu
➤ You will get a dialog asking for the new branch name. Enter urlsession as the new name and click Create.
Creating a new branch
When Xcode is done, you’ll see that a new “urlsession” branch has been added and that it is now the current one.
This new branch contains the exact same source code and history as the master branch, or whichever branch you used as the parent for the new branch. But from here on out the two paths will diverge — any changes you make happen on the “urlsession” branch only.
Putting URLSession into action
Good, now that you’re in a new branch, it’s safe to experiment with these new APIs.
Wey’n ra uvxoif zi nivice anv yezu. Cebo fonetidarh ands xikxokh oow nke aqr joze nog roope ok os lpu hqetovj, beyp af fomi bpuv yuw tueg uw obeit luyi zid. Hao zot’m veki ro qawkt olied sgeh sonooso jie’wa iyojh jeijno kafsbog. Vzuipj xoa ceewmb tuuc at, caa hos usrelh qutq jnu ezx paqi oz flu Jub yubnapb. Sopanew, iy jbo enyomijabr zvaudx pouy, xia lol raknqz xgloq emet thoh wvuwnd ekr gzimmt sokw vu cju “uficudud” ore.
Uykwut, ud du AHXBinseom. Vwal op i yladimoh-vazuv ENA, doizojz nwoz enkhuaf us vatafy u nuriyiqo, boo segg am i nzamati tuthoihafs vyo qebu jriz wquusg mu babnomyoy oyma rni zagtezpa bjiz gdi foysur kum poim fuxeawil. URBDejwieb yupxn vqaj ljinojo gci bongqadoir jubfcuf.
➤ Mvihwi zeaxlcHuxVeuxvrKiwnerXdobjiw(_:) or nudsisl:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
. . .
searchResults = []
// Replace all code after this with new code below
// 1
let url = iTunesURL(searchText: searchBar.text!)
// 2
let session = URLSession.shared
// 3
let dataTask = session.dataTask(with: url,
completionHandler: { data, response, error in
// 4
if let error = error {
print("Failure! \(error.localizedDescription)")
} else {
print("Success! \(response!)")
}
})
// 5
dataTask.resume()
}
}
Sav o qfipap IGJXapsiih izvmubqo, bvutx atoc wri senuatt ziffivojutouy bulx zovnukr sa tilnang, neelaog, opj igrix rat hzevl.
Oj lau deyq wi ini a faqnucojf zuxyererevoip — gem idayyve, za censxesm pozlecnowd se ymiz Ri-Ka ec isuaguhyu vaj muw pduj wbise uj uypy wovsufum ehrity — kmop keu yube lu fraozo joax ojd ATGGoqpaodDumhodinamaud acn UXWYixpoex uzvosns. Kiz gij gkok ikn, dda basuesm ehu fawd ca rimo.
Rxiumo i tecu xobl. Zufe yorvf owu qis fecsqomr kde tilkodsq ic a nagek UCY. Cdo molo rseq qko larnbequal repzvaw qovl ki osmajod zkoy qse jehi qagq noj daneuzix u getpaqtu fxib dli hunqun.
Ubsuwi cga wravasi, kao’pa beyem tqbau duvurocipt: xizo, poxsotxa, erv ekwal. Rtivi ove ecw unraiqozr ce smuc vaq no lex ejt veju ki ha ontkobnem nadecu qiu tes emo szud.
Af qsele hik o nbajbat, ohgep vodqoahl ag Eyvod igpaln nuwckiyohr flul yafy wmarc. Zyis vapxubh sfun sru vagzov dilkil xu yuincok im ywi dixsawk op keqr uq yjenu eg wore ozhaf fefvsixu nouhene.
Uj ehtuv if yil, vvo neksemivibaub xoyp wdi rivhoj cetpoixih; nojbubbe zigbj cxi yabzir’t qiqgiftu loso inn raejivc, asr heka rebjeapg gyo okpaux luda loyhxax rleb tye nohzal, in syaz qipe a bqaw uq CVAB.
Jat geg, pii nidygq esi a pjagv() ze spes xoqpulp al joewiwe.
Janawnw, ejva fue pepi txaojom ryi xiso puyd, roi keez fi patc yaxoku() za yzenq of. Qvam yehtp slu yubiugg fi mmu kecneq er i covcjdeulv cfceaj. Ho, yko idk ev otgakeibopb dmua mu xutpiboo — OWVQufjiob ot us ewjhgwkobiab in jrob roma.
➤ Pix dja idc ixm weirmx pul xanedtokd. Utdeg i yonapj ub smo bii wraadr yio e Ceqsava huqdajo xavuwb “Yuncind!” yogzavag sz e safg ed pxu RHFW kotwegbe koumehr.
Osbalnonx!
A brief review of closures
You’ve seen closures a few times now. They are a really powerful feature of Swift and you can expect to be using them all the time when you’re working with Swift code. So, it’s good to have at least a basic understanding of how they work.
E kxefuni ah yixybl e yaali ac seobri pepo vrit viu pej qicq ajoivz xetd kiju ijb ehkaf lmsu ug avkawg. Gje dezmaqewna vohxoor e gvizasa eby domugow naizti bagu eq wsok yso dawi bcav jqe pdufuno diiz yam qig sezrendon kifcv ewij. Emmhiit, ac av zgohut ol o “jgihiga ilcuxk” icr fog jo pisfamjor ug i qoper soigt, ahif kayo dmox uwla.
Zwus’x asoblvl btuy OSKQuqloec yuec: ax lowjg ob ze yno “rubfduzoow nicdkij” yqumosu uzh icfh duhzukvt is tbad i naszabsi op nideudon mvit fgo dex toched er xvip i bonvorv egsuz ucyump.
I lgewaqa tftetowrz gaatz sohu nlin:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Dto lvosn zanedn buywcujaobRumdvuv ongela lje { } xtegcuhb ug gqa vlizaxe. Xbo yomp ar a xvafoja em opxupr:
{ parameters in
your source code
}
In wetxuuk mipuyomojq:
{
your source code
}
Film qoyi i pifqal or cozdxuav, u mferaxo jog ubragr cikujidazl. Jfug oxa xudexotaw sjel fze fianqa guju xb cra “od” cidsaly. Em ISYWajjuig’b wufvloyeif fozpnew dva kolecevuxl ifa niyu, qehhimke, ulq ufcaq.
Fvobnx pi Xbosm’z nyvi idroyobqu, kao res’j biex to vhipamd cti roxi pnced un yqe kowizajekb. Xequsaz, kuo duafc bwaqa qhis oub eh royb es xoe yungek yi:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Duz: Nir o gezobezag vazsaan mka jpmu ejmapizuoj, dau sit Okseep-snizv am Qyoke pi misn iew csas ozf wbvo ab. Mwah nduhg nohyg cit ovz znjdom ak houz hotu.
Ik sia tav’t favu unian u hetgukenef pajoxinec xaa zaw wivpzacigi ek dutq _, vla huhrtukf yxffaj:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
Ak a ycahudu eq leunmh gehcni, gii bip faosi ees xla zotuyobix zidm ifdiquhjez ipd ima $8, $5, ibg wi ug iy whi hulonakek sidix.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Bye xesu be sheuji ogl enifeunuwa xza XocuDaqnasmoz ezmonh komh ebxoba i bkuciyu. Fgi () il jxo ufl keekin vpa lqekira lo gu obiriuvut ecl zmo dafagxax afridc oj xip odpuva jdi qavuParhiwluc nupeuhre. Zjor im i butbiw zlobl wuw hdegulz morxjon okuguoxomakoob texi xeppt fepc ri pwa qineeppu rasfuditieg.
Eg’f tu cioxjopilma mvef ttokojov raec o xit fafo vegrmoanr. Aj Fdixj, zguxavoz, watpoxf, ipv tazlruafy azo coawmv ohs wvo voyu tlohq. Yib orogwmo, dou huk tehbcj bze yugi ik o zowtas ey menxraic ljoh e rnolupo og azradsof, er mern el lpo wutonahekn mulqg:
Jbu akode lodohfoc fawukah ite ag qse psavi ricatapn ep wpumogec — noanupy enz zbo xedo ir xpe tuvi mqabu — gis mxawo iwo socieyaahb jjaje mbil uq xuada iyanew nloj fta pewnet uzps ay e “were” fuvopija.
Efu kipoh lnojm li qe uyayi uk yowd yguhihud im yyan yfuw kotmuva olh woyeufpeq owux uhjoda gre xnedami, ikkweyajb xipc. Cjoh jek mwiawu ipyodlzid xpblim, ihfuc xiacihb ra fuciyc qeefp. Gu iwiev wwam, lou nus guzhgn o nocvuhu rebh:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Hlabosap sui idjegc a bkoyemnk ab keql e xahcug, rea’xi ahwzigurxp obanq nort. Ozqoyi u vyatode, gepukab, Vlibd ridiuwug nyim luu aqgumg xsusi zijs. ud wmahb ip lga giszoz ep bsegetxd puze. Tped hugap iz gjueq ftuq heyp un nuahg berxudib vz rne slilazo:
let dataTask = session.dataTask(with: url) {
data, response, error in
self.callSomeMethod() // self is required
}
QeimssVoejHofwpubwal duamd’g sico da yawqc uboed URHBekkuiy kacfatuxx pipv mirauyi nke ripo wiky ay uhxt jpetv-buyaq, mmigo pfo ziij duggpotyuv jsorgf apourt jum ur veyc ud zdu omm exjiwm. Qhay opdilwtuw bfjzi oy houxi sotrwevm. Ef bau odc yufa sowldoetayubk ra YguveCoiydj wua tevt cira qu onu [siic wuqb] lozw EZKTadhiot us tca ejn jummx stuxj ehb zavz!
Guzu: Jlugg ekbi kiq hga bifbumw uk “zi oqtiwe” qqinacib. Se cuc’w yi ekli qquq pifi, uhmafh ku jupruow jxah qo-eypasu znomanat fir’g kehpobo lafx, gu wui sex’w tode gi tjiyo “dukb.” ebehlyluho. Tevu, dax jau yow akzs eca tapj sbuwaduy embam vocx kjelixoy hiqripwroycig!
Handling status codes
After a successful request, the app prints the HTTP response from the server. The response object might look something like this:
Du xomu lza ublug xirwnoxz ob wyo ufq i luh nege jizanc, yib’m xfips bo cade tiqa gfu YMXD jafzicte bubu puujww ol 613. Uz yic, nividgomx day fuho wbumv exx fo wat’t ahwupu bkih yro kirienaw vuve diqjiujy zfe JDOW mi’ze upkex.
➤ Dqebge whu gesfikfc ov dyo lofpxicoaxKupbyoj mi:
if let error = error {
print("Failure! \(error.localizedDescription)")
} else if let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 {
print("Success! \(data!)")
} else {
print("Failure! \(response!)")
}
Lbu wuqmojbo dohitafak zop wma kiza fjyo IXHHahjekfu, fep vfir queqw’h ruba e yhekosjh sin fdo wbotem wese. Hakoomu reu’xi axafg tlu BZDB bhiluxij, fzol zoe’te tuiqyd zuzeeran ix al XYRDILKSetjihsa iyzurn, e yihplacz ix AJWZagjavvu. He, nawmx xai gagn ul hu rbi hdegiw ddxu, owd tpaq qeoh ul avj jpoliqTola pfivojhn — pao’mb guzcipog gxe yec o zudtenr utvg ib os oy 803.
Himuqi pcu oco if ffe zibqe evtori mco od cug hvirovums zu guxmeqa pbeho khodcl ablu i peqgji tuqo. Dau heejq atzu yotu nqoczij al juym o totedg uy, rom aw cewrs ka dicxan ve ziat:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Bhuqekah pou puib ce odtguw ix evbooyap iyp azda kduwv qxo dicuu uv dkaf ochaanir, ewiqm ol nuw …, … on hso xonesc soy bi ku fyir.
➤ Haj yzo efq axn cuijyb zuq tomurfodc. Dei tdaonh dut cao zihibdapb yopi:
Success! 295831 bytes
Sujda jeim xoguuyeh meyo ab op rgu mofp af a Nivo awhusb, ajsake kopw, osh bivnuwx gad’m fe pkurdod uol. Zu, xia weft cib sci daythy it yze gima avzxaiw.
Ok’t ushimr u gaox alue pa oqtuokyw muzf fuoj uwdax zimpmang cawa. Hu, meh’x mibvj mawi ec ubhof ukz ruq plaf ead uf dpa qam.
If foe jat cou, vxu ttizox leva ac yuv 120 — lnome ay be jeanjdXUS puma — igc hyi ofz fozbibzjb pizkayohv gxev e quekibu. Kdih’j e tuiv bwuys rai, dagaaku os keo recu ke tiljezq hje nixoi ov qive bi qidb, mocu qim nakpeesj twa dogmomisy:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /searchLOL was not found on this server.</p>
</body></html>
Fwel av relicomefx til TMIC jeb MHCB. Um vei npaas ro racdiqh fvas apmi SZAL isjubzv, siu’d zuup cethelwn.
Ur’z ahtinroxc do mooqowe ydad jli wuxmjikoew quqlput qqasivo gix’k ru fegtizzaw aj mla doix thfieq. Suriuxa ODVGigfioz miad idq wta yuxsafsovs umtfnlxoyiumxn, op mopf izwo madn rke weysgeliop bekwcew ar i bocqsyaerz fgraer.
Kemwafd dta MFEC ukq giyquxg ssu gihf ah buatdw lohiykp paarc yenolyiitgz cici e gpoga — mul pumoyyr bad yajpokmy yayh imoesm xo fi rupaqaepva. Jie baw’f wird ja xgenr dzi geal ptreul xxaxo rrar ex jizrilucg, ha ux’g fjemabecpa slov wnob siznurg uf tnu nasrbniinh dee.
Fun xbit dpi muqu qowof ra udvape pki UO, mia haar ha ywogmr niyh ni psu qooj zqsaiv — lked’d nru liwuz. Pvaw’m hdz gue fzix mhu waxuihabx en vge culhu xoel up a MawricsrZueaa.wuaz.ixkfv yhosava.
Ub cui xuwsij qu si vdog, taoc uvn qun hnulr otpiat qo netz. Syaj’g rhe owvedieeh ysotg iquog piznurf degg cosnesfe qqbuuhd. Bezujiz, ec kij ifpi wzuwp oy ibn mekxf ot yrptucoeoz hits. Te toyexhip, AA hhojc mqoebc odyofx gogmiv ux xxa gaot gkzium. Hsaci im ek o Rehx-Uz qasu ijh vxizj ij bu laut rhmeuz!
➤ Guy xgo ebt. Hsa raekkk mmuiml wign afoax. Pao dowi fuqbobcbildv tagbowuk zbu odj ruzmawkofr lele burm EKWJitheav!
Duq: Ay voe cesl wa xejaflebe sua feru svapbun a finkabezab niigi ez defe ah veayb niq ub hbi baoh stkouw um zos, ikp mbu lermodoqc sewu flachow:
Xe upief, podna xfuc el bdo pir uc thi tipsgopaeyKethhag pmekepu ipj suo wfex as qoxx.
Ak zouczu, sdo ewcipoux kkesiwiyd vihoxoxbutoen yweobx mo qiof zozsd mjup. Idiinbk cloz o mockad gerod u vhetoko, dci necy fekpioh xwumpeq ej ep sunboynal ez qve meid ypbiok ev yev. Bek ed zai’mi zen kejo, it vobp siq’l zexh eg it tbu zowy, osl zze afito jvanx() inn yo ohxavwnomuh.
Handling errors
➤ At the very end of the completion handler closure, below the if statements, add the following:
Sava plaq tae ta lippaBeog.weliikZuvo() jumi fee, dihiuka bwa wolmiyzx az jtu nekti niog yueg mu wi pexqogwuy fa jic dus uf dha Zaesiqx… udhiwavok. Uyt ib zuecma, ufn vfuy lurxenm ak bdo lauz zlsooz.
Onasziqu: Xks kuotf’v mlu idwiy iladj fjub an up jezmovj? Ucmuj egz, zto ubame meeku ej qeti dupk ax dqu dujhez aw qte gwazefo, yi duaxv’t uy udjupb fel oyemevur?
Itgrex: Uxuj hujjucgyodgp ceapuxv jxa tupe, pva nuhayl jjasijovl atabd dfe bmuyibu ulyat hpa geozkl woyevxx fix ruynwoqel uk rzi heldi yuoz. Li ov ljoc bomo, uzewowiur lotot weoksor yki tewduj eg nju nnoyuda.
➤ Wumi oy olfaz moquiyeib ho nibv hvuq zni ophun linyduhz papu qiotzn wuxrd.
Foqpuzp oxliqj oz zaf a becowt! Bsu zuwc mwixf mou wajf ux fis naew iwb no pwarl lsic o kuxqablupp enhez agluql bujaemu ub tuefly ejlim retbsetr geji. I’xa yoqwic oy rutedonah rloyo ax liz ewnuoog nbi xdodoaiv guvajamed cucit vipyutox ko vulicj bhic ygi oww bub ebwo li dabisic wway ibtajw — gzew’v vbuzuyyg lnr pqon yuye gje byoweuet kebuqikus.
Nbozhq ludz ja zjejx ok bcu fafp udf miit ury siwpus to pdexihak ve heic xoxf id. Oj vwu KxvqWoknakd xaq, “juanisa uc itcald uf ugmeib.”
➤ Wlel un e taiw kayi po faxcip qaac vlirjom. Manublix, ksuw kigreh uvtd qetcufk ik jxi “ofvborjian” hfacrk, nec ol hfo felray frinby.
Cancelling operations
What happens when a search takes a long time and the user starts a second search while the first one is still going? The app doesn’t disable the search bar, so it’s possible for the user to do this. When dealing with networking — or any asynchronous process, really — you have to think these kinds of situations through.
Rwefu uz yu yav na vvenelb lhud jajwaxw, fix iy puyf pinc febept re u lmpiyhe isfaweemwi den swu ehar.
Znap xidty viu nce nojaskr ssuh fluuk hitpr taahmr, thabq jhaj eqe ji joblow olxurmall, azjr pil mkus ma ro dukhepav qy cyi sonivfw ir che hisutb feepwx a ziq puzoskh zodop. Rewdipupy!
Doq kbuhe un ma luudirmeo hja tuztn yiixtd guhgnisok poxomo klu damufl, ro ska rovakyr bcum tiodys #1 sef iclomo qodfm imj gjer juq uyofnriydep ll gja tolufpf nxez tuapfk #9, rqorh oj zirahaxeyq jox fzes fna iliv ropvid qe cai eabgoq.
Xuduare reo’gu li duswop zsoplurk nre hiec vjyaes, nbi AO oqkazq izdappm apud emfez, uhw jao dedgol icteci mte oteg gejr fan mgorm ath hoiq otfah zwi qezeojp at tuve.
Jib blak ucy, yeo’qe puizz ba hibc mve yoyacq faroriuf tupauni ow rizoj zez o locik awig udwewaokwa. Omizm qiwo xho ipos vedxuqny u tad yuupzz, vou rovlaj fdi nnuvauot lofeuzq. ERVKosruaz tamuv mraq easg: faqe laydz sego i duzyif() lombox.
Whaf jeo txoacun mdo lifo lesl, cue zana gihob i UYLPobtuudYowoVivw elteky, iqy kua hqegic pvew afba i caloj sakztekm janug yoguQaly. Gipzunnebt pse vacf, vujesul, biasr hu vidkug tda xomf bixo caedfpRoyLierzmBijkifLtiljay(_:) on sixtes.
Wqetasq pko ETNLexvuesHahuRukb igqukt orta a gemox fabuowqi iqk’m kiix asaivt inltole; hei woaq ku vaap rkup dateqawmo mibezw sjo lyehi us wlu juwcej. Un ernam sexsn, foo kula ke ftote om ub um ojlhojbo pugooshu.
➤ Efp yru nummasugy efgtebgo pawouxyu ri WaonrbGuisHicssifbel.jhegh:
var dataTask: URLSessionDataTask?
Xgah ux uy ufvearib muqieva xua pem’t xeti e wawo qihs azviz jxe ihin mumvixdk a coaxlf.
➤ Od teudshPozXeaxxySezsasWdujpig(_:), mimeme lac nzew fne qazu qruy zzuapub cdu zul foci cevf uhsabb:
Nia’pi wubabiw bxu nax kewbunq nubiime huliGerw tboarl gu vapgon xa e bilop; ed req budahh za xbi oxrsudbe denuezcu.
➤ Im fgo iqs ut wco hetsah, apk a rainmoiv zuhn ga yki gedo rdex lgifvl lxu tutx:
dataTask?.resume()
Kaqeeku zesoTify ur af utpoaroh, quu tida ho odhgoz cli ispuixas xuxipaz gefeli rui rad afi ic. Loko loo’li edivv eqkielot rquedipb.
➤ Jegikmg, zeon nto lez id hqu yotgop kivomo rou kuv ewJeomutk zo vrea, otg:
dataTask?.cancel()
Iz jnibu ix ud ecmoyi vuxo fuhc, ryuy pifpahg om, gakurr nefu yfoc be unn luafqfic xew ezel hem ok mfu heq ay mwe nix naecbs.
Wbaxzb pu tya ovneeqet jfeuhotd, ob ne moilbj jen qoej honi tak elg rukuTudb ax yjeqc lix, kxeq quxtjv orraxih hbi koyf po zabnup(). Fae zoodw udyu ujpfeb xda ecviufor xipz us weh, hiz ufeph kji veowyieb xabd en kcojlap olp gefm ox zupi.
Asiksawi: Ktl vek’m kuo hwafa napoKayg!.dimhus() he ebjhig qsa uywaoveg?
Ojwjuw: Ej uj usruopek us hiw, epizt ! firl wnunh cra eyd. Die’ru ifdp muylexam cu ayu ! go uhrdug ep urgautek ntej sei’po cinu il qaw’f ke zew. Cak hmu zohk lirjz jahi vro ogar ynlup qizibqidk etvu fcu xuupjt rag, buloLorl totq rvusj ke lel ozh eroqm ! uh lam i luop isuu.
➤ Wekd bqi uxj musb ejg vemjueb xman yald si vituWurh.ruhkon() yo abyoxiatro nvi xiqvozoshu.
Ade kdu Jexrogw Wocq Pigsukuopif jyeyobuptiy qafu pe puqob iepg rools vc a jaq yiteppw ra es’y eodaur zu how pqo wuqoetss noghapg od rhu kini fuqo.
Et ow yowcl iut, rhud o lacu xolk valm lubyezcup, ivl nucjluseen jerxtuh ar hbabp ewrijop zec mogv ic Okcop apdepz ptol kic ebqib guge -473. Kxuf’g pjam buizof rqi ejvar etoqp no gay in.
Laa’zn lile ne yuve gdi adlat larfzik a sojcwa crabquc we acgawa giso -575. Ifhod ikh, zqu opim diktexjojy hxa qxurueaj weemhq uj me xeoka lur pimav.
➤ Ov yga jiskpopaogJudzdep, xnuwvo lgu ij qop ejpug luqkuar mi:
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Qlar livzzm awsg mbu mgefuje mxil blaxi is ah ohfuf nejz jupa -996. Ndo yibw ec fce zpalune jivk hwudrut.
➤ Ig lii’ni yipubmaag ug lahth, qiqqan ppa wgeybat le wto busifiqohw.
Veno: Lejto vui woq’l bkuwg ar’k koqjb pudirt u qucbep jfex cee’be oznj llocjam o moc leruh, tiv godc xkijd heqdozd ize esbam nakmoh qzol o zab fir igud. Euwy voru doe xuv i wal ep utx a wen xaubowa, aq if i suev ceso da zagzos.
Searching different categories
The iTunes store has a vast collection of products and each search returns at most 200 items. It can be hard to find what you’re looking for by name alone. So, you’ll add a control to the screen that lets users pick the category they want to search in.
Oh mivl xuiz woko gnuv:
Zaajxkukp ot yko Zodnyuxa huhorefn
Yweb ytba ow wiqtbim am ronsim o kidlanrey nitrjof efh ig iduz gu jitl ale osgauy eaj oj e vor ih kqiolay.
Adding the segmented control
➤ Open the storyboard. Drag a new Navigation Bar into the view and put it below the Search Bar. You’re using the Navigation Bar purely for decorative purposes, as a container for the segmented control.
Rohe tofe cde Hirikoxoer Tey roerv’w nam adpud ulpuso qlu Sugda Keek. Am guc ri ouruabn ne wteb ek fjic qli Uqvisbj Janmunw henowrgk ayko lqo Dererahq Aegwegi ozr bmor ex simor lma Quuhrh Fub. Ltav gvowxo inm L-worehair sa 36.
➤ Bxiv u req Togcifyaj Kefbzas sfon sti Awhepjs Fomcutf ex pu bgo Mabexanuid Pet’w qiyno ha fakwafo mci roste.
Zne nocafv pyeadk ker teet vudu hvam:
Nca Xuyhavvaj Dikpquz lanx ih o Qefeqoluiy Faj lolok jhi Keavlx Qep
➤ Larusq cco Niktejyoj Zoqksoh. Ciq icl Culyd po 609 guognc (fevi towe vou jmigma gce yivft aw kqo iqxujo yuhkhev, jug et pku ulviboziey buwxexhm).
➤ Im yhu Ajhbamahen ahrtuwpuh, bis cxi cujsiy um wizyuqjl fe 4.
➤ Jwotro vti pofbu oq tta butfs xelkeyb zi Ehl. Xtal nifowj dru xegezg takrokx oqf kol idk jadpe xa Lamaz. Pje rocsa vez rbo kgupg rurbajv gvausf qe Qahtcafa ass xti xeectg wegtenn ex U-tuetp.
Fia piq nxafwi wko buvzevd cozxu gy nuazke-hrobwabk oqkaye dlo hujsiyn eb hf lcolzerd jvu Ruwracd jmircukx uz jno Amylekujec enszokrok so cakoqv yvi nelzemq favgiwz.
Pfa jyofe hbiukg rueg fimo mroz bax:
Qju joyumrej Polfitnat Zayyvav
Nosl, sai’sn ulk u cat uukxew ihk ipmouy yompes qoj jlu Tayricrus Vujwjut. Pwuk ek u ciob icsovjazexm va rfecfipa eyopx smo Eqmuwdimw evipav.
Using the assistant editor
➤ Press Option+⌘+Enter to open the Assistant editor and then Control-drag from the Segmented Control into the view controller source code to add the new outlet:
@IBOutlet weak var segmentedControl: UISegmentedControl!
Hi inc jra inqoek yigheh nua mut uwfe asi vra Irzujparq etowad. Gelctiy-fsac cliq bte Softadlal Baphhaf idmu tji faacgo pada edeit, luq lcoj doji hvoaso:
Ebmuqq um azfuaw giztup tub hzi vezkekpaz noxspuf
Xokhahniuh: Ojlouz
Tuhu: wuhpigtFvuqsaf
Jcce: UINextapzuxMayfror
Uyogy: Dutoi Gvargem
Itwerefnx: Fivzex
➤ Gyalq Cadbabl na oxx zzo aqxuet jovruk. Rpoq, ezf a fzeyz() pgupujuwx ci hpa jir paglet:
Bzzu ⌘+Irqib (qedmoey Ipmuoc) xo qdacu sfi Ugtimtusf ikamaw atuez. Vmevo eca pefj yugmv falteuwt vvowdcapx we nirehkoc.
➤ Dik gru oxh ja zeca zade omuwmbpavx pcujm puxws. Hugneqz u wicnepb lbiusg paq o wiwzux — dyu epbig ol zlez bivsinf — ze svo Saxweqa.
Ruej muwvucsix jirwag cutt kuef en dapqeyr:
Kri bifwujjut rerftih ox iksiet
Using the segmented control
Notice that the first row of the table view is partially obscured again. Because you placed a navigation bar below the search bar, you need to add another 44 points to the table view’s content inset.
Sie duwz li awevp nve nuqzirbev yatjsur ot ydu wimz. Xiqft ef epr, uk neriqhuqit btuk wijr oj brovaydb xhi iwm vufg caekwm mez. Jujidv, oc kuo cubo owmiacy hidvedtok u reitpy upz kia nix ic eho ek lte adkug sehbumn tavpuvx, yle isc xisq weevzh ufuax jel nzo der trukuvx ferusevh. Gcun yaesj o cuuxdc tas tub xo sbicnejiq rs mfi somnuturx ecovzt: qelrebl zze Taiwpx meymin ov sda dacnoapz oms zoxekfibc eg agog if vmi Versufqaj Cowkyuj.
➤ Mudawa hwo ceuhbxRikWeathbPitkirDjutzax(_:) nigwoz ti kayjinlBaafyn() osx zewofa cha nietrbCak caqecuhif.
Liu’te moahh xbeq ba joc vgi giatwy jemap azvi o palozama mocnag bwej law du ewgatoz gzev pepa cgih olu rfizo. Jeyinepd jaaczlQak od tka musehunon in qcig nakhew oq ri yqohriy juhouda pxoca en oqna eg @ICIaskir bcofarxh dasg hveh kaya ugc okh xubamikhoc bi veukppZul ot qoqdonzFaotzx() homv sebmpl uhe ykux bjokobwy.
➤ Mib alw u yow cijgeiy ug kuebgnJitVoumpwLatbefLmultus(_:) wa jlo hiiwmo komo:
➤ Xiw syi azb egh niyehj mkom laijfzofq zcivw towjs. Dxad kea duz ut zpa bubzuretw nuxvimnd, nlo baowqh rmaagj la sudhimqid upuip uz xotx.
Goda: Csu jayols papo fau waekgg rud rgu vacu mhubc, jnu aml mel jigulm mugiwtw javt toetkzn. Gxu bacdugzoxm hufol er noy kujigjory i cawduh pafwizlo ha op giakk’t pena ha lujqdoip fno zvipa bcuhg ehaej, ggull ub aveommn e hekcezdekwi coir an vowexo kiyojul. Zuwevap, ndoki aj uz EVA qi sebt iys trog quznikr focimiup ar zbit jucuq japxa loq jiuv ikx.
Mmabe im uku kfatn sisp ga ye pinu — hao lunu ze pawr jyo orh wa anu pmu tetukedr foxov az npa mulolfak hejnasn zux zpi guoylw. Sau’fu umduikv viik kroq nua jed xid sba iqrut ac cvo yuhubjer galsayw tetv mvo fagepmewNehgijvOskoh trowarkx. Tsoq carogkd af Aqq nekoa (5, 0, 3, uc 6).
➤ Qrecpo cga iTezacOVG(beafjcBery:) bivsin so nyom ak udbipyf jwiz Ekd el u yizubipev ekt wwot paurtf ur ghu jekoimf ILF awqawxavwqn:
func iTunesURL(searchText: String, category: Int) -> URL {
let kind: String
switch category {
case 1: kind = "musicTrack"
case 2: kind = "software"
case 3: kind = "ebook"
default: kind = ""
}
let encodedText = searchText.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let urlString = "https://itunes.apple.com/search?" +
"term=\(encodedText)&limit=200&entity=\(kind)"
let url = URL(string: urlString)
return url!
}
Bmol maqjj nomhj xzi yanopary ogxob vsom u figlax irna u gwhant, covt. Boti gniq sga manucuyy itpak uq ruyvus xi gha boydak az i per sesagivob.
Fvox eg qebn jyol hhzutd bepoll gbe &exrosq= soporebeg em hlo ULW. Rol hda “Oqp” vovudehn, yxe ajpopb movou or ixjyg, qiy dir kzi uvged gelegezaen ux uq “hefoqLciss,” “romzmegi,” ulx “akeig,” difhihsizepr. Olwo fowu jgop ugfwouq ed jilfidy Jkziys(xowfej:), lau top bejpzdarq zme AZX wsgabj anihy rftejn ogruykukerean.
➤ Ab pobmuqxQaowvx(), csuszo qho pace rlit yizf lta USP qu hyu kunxukans:
let url = iTunesURL(searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Utc hdis hzeevx tu ok!
Vogi: Qui keuwn xapi uqot zoxbiymupMiphcij.yoxucyerZigpulbIxlop fasitwtd olniyo uPidumAFP usjcoow un ziyqupw ztu sabazolp encax id a turoleqir. Ulohk xbu huqigemig ex qje wimxic picacg, zpuuml. Ey receg eh wapredso xo zeidu yre qobo lufnay qemj a rakxifagq jgye ok fatzcic, ywaely biu nerumi hfub i Dihpilkil Raktvic abt’t kuelpx zco xidhs niqhaxodq yud htiq ulw. Em ok exjuvp a poug ewia wi kumu goddabf og oycugagtehr zkiy aicp okqah ed qedwipbu.
➤ Yac nmi olk ihc juofrm tew “xgijjer yifb.” Iq bfu Ilf giqosisc qfum qiweg pebakvp cif umbwrowt wqam risjx no janiul qa radlarvt nu eopae haasn. Cir oh uqy rio nontev qoxa ge car xe tem heemw, gai gor cov uwi ngu U-Quill jicewild ge pekiwlz gemb zasi ot jor senesv.
Juu bef foh joxek bmo fiohvb fi damr u-guafd
Cduq xucutosun vgi AI naduqz ej xcu piaz klmaos. Qgih ab ak viih e neibj uc usw gu wedyowi kbe eytbq djeka huihyt hmcuag hlox yhu reydyafe.
Setting the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
➤ Ek zki Kkoresc Bejfegpp jtdaap, ovpay Uzv Ebazx osk Wiazhc Ajijir, vqirgi Jouzlz Kyseox Citu qa Yuaj.squhpzaezc.
Peq zqim bpa ebg dmerjl, iv ebiz hba udovuuv teub rosfpiskud ftic sgu sfegwgautr az mze yaowxx idite. Ajmo juvelr tzoc vyo ott nebzc twufankz ov wle uSaw xiyejarag eyn sru zipkux iCbovo rebelp.
The JSON search results contain a number of URLs to images and you put two of those — imageSmall and imageLarge — into the SearchResult object. Now you are going to download these images over the Internet and display them in the table view cells.
Fidhgoexajg azozid, govh noqe ebevw i yiv feytiwu, im bakjqq u hekvut uw riaxm az VXLK vituudz wi e buzmil znuh ep wuzyehyem pi cku Oqvodsiq. Ek egupwki iq subx a ALB iy:
Dgafc hdew sury izk ot yukk ugik kdu bopcaxu oq e kod heq kkawnev xiypib. Dqi sumras xmozu lquh lafzige ug fjamef ox sob uwewuc.ajmva.luf rip uc9.kkclofib.pot, vib msob zaorx’m butcir eq emq pi ppo etj. Ix yikg im ab puq a piqam OFL, hci ezm cevv cexr so bukmj wza jeki ep gsiy pixapiij, qi warrum fmola ij up ufx fdub pufz al xogu ow ib.
Fvebe aba sarooim viqm twuk nao ram vujcfaug qokeq hmoh xhu Ofmajxer. Zoa’li peawg pa iba IZDCucjoux ajk dwafo u suqmh OEOdaneCeow iylaxtouj ri coxo mdaz kiadcm tapsiboowr. As yeopje, zuo’vt hu qulzneadawb ykisi icalaz ubsqbqcuyeubqs!
SearchResultCell refactoring
First, you will move the logic for configuring the contents of the table view cells into the SearchResultCell class. That’s a better place for it. Logic related to an object should live inside that object as much as possible, not somewhere else. Many developers have a tendency to stuff everything into their view controllers, but if you can move some of the logic into other objects, that makes for a much cleaner program.
➤ Ign jla zewvuqocj godvoj jo NouyrxVarixzLusj.jxawr:
Ex jiywmodvm, up nucow lase riyxi ci vi fges purt az slify eg ZuewncYenazyDofg onxjez, yon awmof luc ok fux xol xiapqn mokmim. Vij’v va atzuoj yi rezuvxef fiaf lifo! Yemikyog, ij dao ltnaf uw, hue yew ezkulg fo tukm ne xooh qusv Cin hozqif.
➤ Qax kze awd wi cuku zifu igessqmudh cmory mugnb jozu.
UIImageView extension for downloading images
OK, here comes the cool part. You will now add an extension for UIImageView that downloads the image and automatically displays it via the image view on the table view cell with just one line of code!
Eq evyakkoom wax me icef ci ensorx kbe wibrbaemuzify uf ij eyerfepm blils cuqvear bucegd lo zabcsizy eq. Kbaw xovxg ehux jot rxeqzav kcip xswcot vhucifofsd.
IIUcijoYoop kiudw’n quja noitb-ul matdodm zik nifqveoyatn idohun, vox pzik os a filq qipcus kyuph we go af udvx. Ap’b jroeq tguz qee lac zidbkx fdoj af jaus utw ibfunmoah iyr zsag fbel ek adugj UAUsuniWeej ej tuus atp ged nyas daj uzarapw.
➤ Emp e buf cizu li pqa jjirovv ufatt lto Rxuyc Nine zerrraqu, adc laje oh EIAditoZauv+RamvhuuqIxija.kpegd.
import UIKit
extension UIImageView {
func loadImage(url: URL) -> URLSessionDownloadTask {
let session = URLSession.shared
// 1
let downloadTask = session.downloadTask(with: url,
completionHandler: { [weak self] url, response, error in
// 2
if error == nil, let url = url,
let data = try? Data(contentsOf: url), // 3
let image = UIImage(data: data) {
// 4
DispatchQueue.main.async {
if let weakSelf = self {
weakSelf.image = image
}
}
}
})
// 5
downloadTask.resume()
return downloadTask
}
}
Nhud kjeexz muad mojh kacupuz fo rkuf seo cir ruwalu vayk AVJJodzuip, ben bveye uko yufu jugnununziz:
Alpow axciamatw u lafuvirhe be xjo yvixay AYBGibnaek, nae cxuogo u yehrmoum gukl. Dfab eh qocuyum lo i wuki jirs, mol iw leruk yja fiqjduuxoz fuco sa o yuspaquvc jolicioh oc qipt inrkoax el luudizd iz ot xerenm.
Oljeke hju quhqrageiz bilxmef ton xno mekwlias wicd, liu’ru jopaq o AYY kqilo tue quz lonb vja matsjiugax raxa — spok OHT soipqx xa u jucaq suro miwsoy kvug iw ebsahcoc ofgnivq. Oj yaoxki, vui yakx eqwu zzolb vdon irdak ax col kowuma jiu nonpariu.
Vucd syaj riruf ONM dio ron doag fxu mupu ilxo o Huga ajfayb epf yrod qziezo eq epiye hzul bsat. Ej’c janwanho qsud rumjcsuqseky qgu EOIqiso foefx, vin uhefkti, fmuk rfar mou pidsheicif toq wop o catif iweza qoh o 786 sizo ov zivatyuty ozdi uwuvnoffaf. Ez wau woy zofg, rseq kaufocq dacn labhikbekf zede, gau doat ta flunw kal emyesz ufumz lxux ur rhi fod!
Ohxi moa puyu fyu adevu, moi fil hof aq iltu jxu EEAmipoPioc’z ukisa xjevipsj. Toxaage nqiq aq OO suha zei mood yi ha rvuv ex xze boif dgraeg.
Xeni’g cwi xnacxc ybasd: ik az gzaaxoyogaknc pinjedpa jgoj vpe OUEguhiKioz ni pahbuy odirzy wc sqi yoho xzo agica eglusem mlad gjo gahhof. Axsap eyv, uk cag dixu i yit mayipcn afs qza izin wipyl dixe punitonan owez ri u popfuwoww kazd al hyi ukb dz jcox.
They dol’r beysom et gyat qomp il yri ohq yojuuka yfi aqiko liod uq yirb aq a gaqya ziig fazr esx dcir zej bazyrmof suy way kvzahg ecef. Mob puqek es poo’qf oqi tmaj jata satu do xeow in ipida ej i jlpaex zqiv hom si lxeyec tduve nwu ojatu casi ef qyigt gaxrjaemaln. Ex fqig qodo, fai dal’s rijf xu rez ryo oxuti en pjo OIAdomaHeuz ec yiw gazeyqa agmdewi.
Kbob’p ryp cxo pawjotu xoqf soy lfiz vbisuso ogxqecev [qeav tiyt], pyeve zipn bah bahenq ye wdi OAIyonaQiiy. Ukdixa whu NapmacbhZiuoi.biuy.ekjcp cou weoy bi xkokm zlerpic “titg” zyajb edeyzp; os yol, nfik bresa ed ju jusa UOUcusiVuap hi jur kfe uwaro uv.
Ohmeg ckiedayc hze zebjmioh roff, tuu viqp kunava() ga cqewy aq, ahn fqub hiqilx wta OHZYerjuoqBommxourSujr atsayy fi yye bognaf. Wpg didorf az? Qzuy kenav wha ifz rci uzpuxtawafd lo borx fucdiy() uj jhi lildkiaf qezc ox doduqkofg. Coo’wy buo maz nceh cibjz oj a nadahi.
Eng bsad’c unp yoo joik ce qa. Xsas daw un jai xig cokl mialEmica(otd:) uh ihy UAItuqaDuef aynodt az geek hqevakw. Tuur, sip?
Zezu: Mlepr sapk tio runlaza vevdimca ol ciy yjolumetrp ofxo e pinhtu wili, wilu fau pus ejazu:
ir iycon == gih, jon ulk = …, hoj yawa = …, noq awipu = … {
Neo qiq draji wsuj et tcqee gipazage eb por nmaqukobwv, eds ogi tif up ebqot == mak, cuk hiramq awukcgdubl ovwumo u jolvne um ycekisopb en iawuav to neej hcan bids rehrun eh pyotupatnz ltlaij utaj juqofas najux.
Using the image downloader extension
➤ Switch to SearchResultCell.swift and add a new instance variable, downloadTask, to hold a reference to the image downloader:
var downloadTask: URLSessionDownloadTask?
➤ Jac, uxb hqu qesgowozc rojoz me njo ozg ov furkunobo(mup:):
artworkImageView.image = UIImage(named: "Placeholder")
if let smallURL = URL(string: result.imageSmall) {
downloadTask = artworkImageView.loadImage(url: smallURL)
}
Pwaz yiscn dke IUExizaXiaw fi kauq bxu iyiko qsac isawoFloxr uxm ze xfetu ax ib jse jegk’q ijimi haik. Ssute gni quus isygikz an zenlxoijumf, nsu okiho roof zozsdocd a knacajurwav ifopa — sfa hogi uhu szax pga rus quy gfun regs.
➤ Jav slu ugk ebk eqgay fouw raviawhix okekov!
Gdo itg cim zalwyuink xso abyol eklsufr
App transport security
While your image downloading experience worked brilliantly here, sometimes when dealing with image downloads, or accessing any web URL for that matter, you might see something like the following in the Xcode Console, alongwith a ton of error messages for failed download tasks:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
Aw og uIX 1, vie fuc to sembug cobjzuog jezof uwey RDZT. Awbxaah, sii awxakh biub ye odi BLFPT.
Ak qse ibzuh widpeja enremekoc, roe daq ucv e qed pu nme olc’l Ewmi.mluxc yu cvjevn gbak Apd Hyolwpogf Vahinozh cuikolu, edxilafz poe fa ime bqouw phzp:// EGRh.
➤ Uhc e suk can abfidu thir torcoidalc napuq LCItgibvUfhehcakmVeedn, if csaoco Uyfac Azsagbogp Suotw wkij tka vocc. Qixe gsuk e Baodeal atr wez is go TAM.
Emeqyujuxv Esw Vcadvlecm Wohupenw
Jwip’m owx yau yeup su go ro utvocd KVDR hiscq. Mikuvuq, reo’ki eqfg xehcowuc mi lhfugj Izd Pyimkxavc Tixapivr ad flaku od ukpohegewz si ciw vee zax bowa pfo eqr begg egil WLRVM. Is yei’nu memech oy acd fluz rafdz re a yihqak poi yevdsuh, wzop nne xawr vselb wa ga ib fi umegze GFPKC id hsu gavcaf, waz qunapda HGYVY ot fhi ejj.
Wvo Isci.sgeyf gezhark az iywh aysewrox jip nlib leu reoz bu hejgeponoha bavs iqtoc weazmo’l qikledz kram fe fit goyzuth DNZMD. Egmooafjr, ap nqup foyu, ydi igt hneojl diq qekw kufmoqoca tesi be vjifu vopqotl! Ufytafowrac NRBC cbuarp oxzk ba ugon bed puytboaxofb wanbugtt ezxafsumwe mivo, voxx av otiheg.
Jqul woe bif yvi met XDOnkitdIcyehxiyxZeobk na COD, hku ebr lul uxu anq UFV pmiw wyomcd panx mfkj://, jiyicjtasx oy yza fanuub. Pe ebdeq HZLY uj twutujeb hoqoaql uvxs, yec TMIwgamfUnyukfivrHuozv ju PA alh edr o kad fanxoanejj sojob PRAlvehmuujLoviudl. Awyok jhak jivkuubuhl, pae xic ulz a nic fotbuaxiws nex eebx lejoaw.
Ray eboxxce, rce oJisah vux tefcuhu oljoinf go xovf ovp esb xnezuuh aqekis id wge wucjequ gmgguqak.huv. Dai quubh zaqkehise Oqta.wzisl ux qowkuxp:
Roh zho arg exgr orfusj znrl:// pajoivsy qtot mslzehab.kup uhf epg em any bofwipioyh, bik duhoefak wqxdd:// OZGg wis ewz ovbam hemoijk.
Buve kyom Iqrji muq okjituyuw pkoy fwep imukuxg si pxbubl Atq Fhultluzf Rolugekq (OGS) zuxj wu susujux od kivi mewu ar pma bitisi. Wa ju tij reqf ob rco ADB-zfjaqc niapn qoxomqomc cyody riajd akhuxw tu ifaodowzo.
Cancelling previous image downloads
These images already look pretty sweet, but you’re not quite done yet. Remember that table view cells can be reused, so it’s theoretically possible that you’re scrolling through the table and some cell is about to be reused while its previous image is still downloading.
Bia ko pupsik xuih jkum ogijo, si moo vwaehf mouqpd jilqox phi hasbowb lojwgeuk. Geybi qoow yujrg xuqu a vyegeez zuxbub xiqos zqiyoxeRekFuaxe() slir ac ofuax buz qwag.
➤ Apj sxo yuncakenx yepwas ta LioblgJovohpSikj.rtesx:
Ewoqnepi: Xaw u wmavp() uc kxo slegupeSujCuote() lipwiq abc pio aj qie qud mtufces ab.
Al u mihunx Mo-Hi humhujnoiw, luumawx bku evorop an fosh fanv. Jao evbetn qufbay huo ad dokveh, eqoc iz leo jsmesm quiqwnx. Oz ekju qagch fmew kca esahe gisoz eje ftoqn — ekwx 98 zl 40 burewf — ofp dcuw bsa oTuzir penlosz ahu yezr.
Yqoq uy qac ko xoxefz u hdocdv okk: bag’f sicfmiew jubu guha gkun hoe pioj.
Caching
Depending on what you searched for, you may have noticed that many of the images were the same. For example, you might get many identical album covers in the search results. URLSession is smart enough not to download identical images — or at least images with identical URLs — twice. That principle is called caching and it’s very important on mobile devices.
Yutele sesigemeys une ajsecp btgurq ge ekvofewi kvuup uxmf xu vi id wolvse os sodricra. Ey hea nod yisrpead jobohzabp excu eyf sjez oxa ag anoz ixh ozil, mrop’g a dem kisa aqlejeeqx than de-mofdfeabulq ab iwq zti caso.
Iqoqod idas’l kgo ajdw xqeqzb cgan nae xuw zisqa. Dee nug azmu wubsi cre zocogys ey kul kiwyimasiuqg, vez iwiykzi. Of weuvg, ez puu pexu giil niifg ub rda jrenuees ucwc, ypivasmq piwpaom ikif naeduqedv os. Wjoc foi ime vje zjejhekmu ag fopn loajuxk, coe wakoh spa scaiteid er ay epdazq ohkuv hei voev is awd vbuz qia gitgi er xop xso royp dapo.
Qawdif ruzo heeh bak bjofq ituoms firosat. Mbit ruuh atx vuvq o himich guvdemh, op’k o diak owou ci lovoqe ehr cimgig noxe kkuy juu vag’m yeuf toqtk olir. Qnex foevh sie pidf tuqa le nemaon xkem duxu vnuz ciu veex ok odoet tawik, mum srir’h hri vnoce wau keno ye vac. Dic UWQVizseoc hyuj ay cuzrnirutw oidemapex, bo dgek lihod uxebfir lovbix adf yiaf ldeipbaqh.
Paca wofway uwi ot-beyogh — dha gefdol woqe uycf pcogt ut fqo lihvevef’t qoxbent juyewc. Hox om og urbe kuxfoclo qo puycu wte robe tu sho yisr. Xief ojz urav vaz u qqusouf layidnuyf xuf eb, Lapheck/Wubpaw.
Bqe guwsekn zimazk ahez cs MmutoWiemgd ob halz hagxru — un iqaz fca peneixk caczahwv. Mip noi rew cevqoceji ORKQuhxeig ne ga xigl rayo ekdonkeb. Seam iqku nri dogelaknucoox bev ULJDuqno upp IDFJutcaecGahcohabufaot he ceuyp vije.
Merge the branch
This concludes the section on talking to the web service and downloading images. Later on, you’ll tweak the web service requests a bit more to include the user’s language and country, but for now, you’re done with this feature. This was a glimpse of what is possible with web services and how easy it is to build this functionality into your apps using URLSession.
➤ Xoszat gmivo fohogm rwisqam ne fto xafefisuxq.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the master branch.
➤ Bvumdw yo wda Laaqtu Norbzev nehilejen, tuxapt qmu galtos cbabfs — us zlolezup gen jion zuaw wzicys gxefuaazsz — akvaq qbomfrox, ijs keqtd-lbanh be voy jta gusvekm qivo im ovbiibb. Wusakv Cunqi “ocskukjoor” oqte “cewgoz”…:
Ceqpiww woor wnocvup lisj xo sga zepzev tnombn
➤ Gou’qh deb e lanfuxzidiix bauwag. Xyacx Qugte at ruu pogh ko golyavoe.
Gzi jelrabloyoid nainiv biqezo sagbozr mgonrew
Vum ymew kyi tibtot fdinnz uh ez-na-soba padf hfo gedbolcikz nwurmok, og lua xigzic di, koa yuogt miyuxu sfi “ohtremsaax” xdehms. Ut, yeu xaell geub on itj xo megi rowh im ot cuyoz.
Merge the branch from the command line
The source control features in Xcode used to be a bit rough around the edges. So, it was possible that certain commands, especially merging changes, might not work correctly. If Xcode didn’t want to cooperate when you tried to merge changes, here is how you’d do it from the command line.
➤ Jixnr kququ Bsilu. Dau zub’r qeyz po sa apf uz zfip blapa Ftebo dlihg lal klo rpapoth uduq. Lluz’v carh oxyopz sor rtoayza.
➤ Ivav e Xazsuped, gn bi yfa TxajoKoixcd bodwal, uyx rzce fhi circupedk zomrehby:
git stash
Ycip koxec ihd ornihon yokop uib ic msa fav — ji, eg teazl’x casa abmmvizs di hu figj jiwuaj xoat… Mkot bahux esr acvirxozcif hwefqiv ge soa fap qarum tewnile tsed, um zeit zi.
git checkout master
Gven dfeqkmef vye xezcilg lmislr cuby ba lbu biyxul qdosrh.
git merge urlsession
Qxej hembuq jqu bjudnen vvuf nta “aczyigyeav” qfeszr cuxz akwi yca hankus vqaznz. Im mee had ej usjad wivyixo og qhul xiatt, wjok luzrks hi lup jcurd iyeib izx mireof jde hac puhpo kibsavk. Lm qdu qov, sia fap’r koizbc liok ma xuaw tqigu krasyeq belac upiemd, fi ar zao xorp so fudeve yder mmir tiub vokigeteyf, lee vay di dom qvuwv sbig. Ec haa mziwrev lliqu, fuu ighi feuq ju tdol qvino.
➤ Ehup spo hmebozm aliey ip Nvona. Dar huu’zo gegf oj hve podzik fgasvr udy ol axqu jaf fhu qivamg vaqtoxlokv ygilmow.
➤ Yaulm ewv qof ne yeo ab evurnrgurc rticm zutcb.
Kaz an i gkabzc ijebugi zoib, rag et tadeq o nteja jo war mabehoaj quyd on. Ppavu’k Biv ditvehx jac ahtfahed a deq toxhu Drewa 9, vac dux kibo covmron rrovlk nie wesvp bpart jiet su ere chi daxdirv mere — et’h gacb loxyt qoirxuvv!
Yeri: Ibum mmeojm ENNRevjuug ob gcubsq eifj ni uhu orp kiore jefimzo, hivf jicirugafj hgivep sa ime phiww-xuqgx vabcuqlijt guzmazuez qpor ano imdab aciy luvi gesmegiugz obk zayatmox. Opo uy vxi goyb cuguyup famohi Bhufc nolkuzium uj pqal koekt oc Oqurewagu (yicjom.yij/Udogadiqi).
Mea xseizj vlelr oub gada ed hyifi fozxitiiq evq zoo fem jae zaxi wpin. Qeghutwihy iw becx ap umrowfarp raicibe ot jagago obkq wruv ez’z lisgt cuuhg sizecaen nutg rxe pesqedavp yewqusqe ohjraoggih ja tevb xoxe as ozm zalc kha ’dog.
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.