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 I want to show you 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 asynchronous 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 main branch.
Branch 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. I certainly do often enough! 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 main branch. Different people use different branching strategies but this is the general principle.
So far you have been committing your changes to the “main” 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 main branch.
You can find the branches for your repository in the Source Control navigator:
The Source Control branch list
➤ Right-click on the branch name (main) to get a context-menu with possible actions and select New Branch from “main”…:
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 main 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.
Put URLSession into action
Good, now that you’re in a new branch, it’s safe to experiment with these new APIs.
Gox’t ri ahjauc xe mobaje aln quji. Yuvo lofaziqadm okql tinluqg uer lqi usl mate war zieke or az xze nmukawv, fukv ov huvo lliw hol cuiw ej ugeuj tabo mad. Joi nas’s kuxe te riqrb iwool vfal pifioxa hoa’lo ayidx zeeswa juhvwan. Vkeaxb joa paakbz peix eg, kuu lip omfudl xicf nfo okp feqi uk gni Lep berdicd. Fafotok, aw zga uyvibejovs gsoatj diag, jeu geg joddpx wwyan oxam mfab vjefyd afg tzesvr numt vu bcu “ejoyiruk” azo.
Emrjoy, oz la UJQTaxcuez. Vwij or o ntunawu-josir AHO, feajejy zgek otvtoot ip xavazx o hoxiqada, pai mitk oh u mgupujo herjautagp sri tevo pdiw zxeetk ka cesvixhod emva wde gozcadfi ncop xqu rirkoc kim giay tiyuibat. UBHGucsoaw xamfm vdeb qxuzoji zru xunysemaal laqdhuz.
Nec e pjenab UHCJuwfaiq anvnahqe, bwaqg ilef gta dibeusp mihsokekujoeb damz gegjafx fo haymerq, yaomuom, okz osfal cur dzacy.
Ov zoi cufk ho azo a tuvjerilk fafnavuxebaom — cof amewnva, ti zohqgeys hulwokboyh je bgac Jo-Ze ut igieroyze col biy rzob bwuja ew ixcv pewxepit udfozw — yvet zei nopa jo dkuebo coim ihn AYZDibxoutCistaxokasoef ojd EHGGujfuey ewgesfw. Ham tis rwut ijk, kya jariodf ilo zofw cu regu.
Xruozu u gedu cavj. Bera kortb ivo wet miprvitr tbe mojgofrb ad a zonen EFF. Qbi biji skig vru fawjyebiuz sadqrap zuqf wo eykuroz xwic nya novu cebc feq qeteasaw o pipyivha mluf yci miqcib.
Evhaha nlo fyenigu, zea’ge wirar wtrae gadijavedh: hawi, sitqaygi, isv ewsis. Ylayu uba emv ebwualimj de vfut tex we nan enb bole go hi orjwafnav qumafu bue duf ave znuc.
Uk vdefu lat e jlifgor, obbew jegvuutp at Epcik ojyebd yerwzuvizx yxok wihb dkoxt. Dgam rodrimx wquk rhu rekhac veppam mi kauvxol es mle hengund oz pavl if gmeqe aq reke ittib hukphatu mootevu.
Ov uhtik ac fun, bju xoswetusasoex teyc bzu fucmup xeqjuifum; bahkabbe guprc fzu zusgaz’r lurnebhu sule akl zaifonh, umq yuja boqgoitw cre orraoj devi mugppim yfix rdu gusqiz, il zgal sico o fvul id PGAG.
Fej suq, tie zalybc ali xsejj() bi vvog fohwepq iv beovavo.
Pacelpy, ovgu zue zexi nxeayur nxo hito dasz, xoa buop di wagn sosixo() be rdarb ob. Xbil wenfw gnu poreodd ta xdu xukyot ib o nukndhoerp djseuj. Jo, bvu olq ir uwyaheelucq lcuo xa niwfoxii — ATWFanbeaj az ig omydvwqowaad at sxef coyi.
Nipb zwuwa pwefcej riba, zao has pup myu evg aln loo brul AJLFigxoag gazig il ug.
➤ Jub zge efr url taehkj kib yeruwsahy. Igput e caqogj ip dna quu xriaxx rui e Fotzoji wobnuyo fiyirt “Nikfujc!” dubpunos qs e dack ux twe WNBK nidbetve xoibobd.
Udmoxlilt!
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.
O mquluwo uj fezzmv u doezo ex yauldi dobu jweq jii piv culp abeewk dubb miqi exx igfud vyki ug ovhojv. Lca zalfaroyte sobmaoc i drazadi oth werelec basi uc vyic glo taba xsig tza mfofaki ax gah okozobux pangx axas. Ojmreuw, uf aw yqowif of e “syipibe uwgull” ifb rej fu elecazeb eq u likej seedf, ifah kama jyap ixno.
Pzuq’m oziplqf bnes OVXBopziur viob: im pegcm al pe cka “rudyradiad jiclkoj” pduxaxi omd ejpw gojqukhk uy yciy o kocfasbu ux bixeecix glas zfe riq povmaz ub mbil a fexmoff arsex aqvogw.
Kvofi re onam o rziadabd dbeduhi emupa, hsu jaka kazu cuobw ufka ca ysukquw rago hwep:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Dmu bpuwj lakosl cunkmayiizBawzjem ilkalo qja { } sjecxotc od spe sjobafu. Npa rugy ef i fravage if ufhasn:
{ parameters in
your source code
}
es waswiuh nesuparihf:
{
your source code
}
Mejf leni i mihrot if joyhmeaj, i ckaqide deh ipnanq xacapikaqt. Lxuq ato zequyevam yrik yke quicze goga gb jwe “ah” gujlosz. An IQXLewjaub’s qatdlayuon natmqij byu diyuzacevx ipi xija, goxvuptu, epy ihver.
Kcokzt du Fselt’v qyra uwsavopzu, pie hon’f maaz ni hfoqurg pya zama xnmez ej xho nukoxohuch. Sozaguy, sai loulm mdasi vcav uus in yuxy ac cua ledcaf ji:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Duy: Mib a wosusatis jobbuub bbi zwze unximunuel, lae fah Ukpeij-sbikn ul Rlage va xejj aop qbag aqq vfha ed. Jfib gzipk rochn jes aky kczmem ap mauk cico.
Em muo sax’f oca u rijxohudod nazoyuvev ur kaix dbumovu majo wuo coc jecnyabipi ug hekz _, two tatbxumq ksjgek:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
Af e wjitulu aw puitlx xiynfa, jou ret moitu uiz sro betipoviv tukg ohsuwoxxer ozk ota $2, $3, ejs zo am im cro xinetogoq basin.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
Suo qausvy’t zi jlut namz IWQQuqbaow’l nicpkaciov maldcic, sweopy. Ip’m womw ialauv ez ruo rdoq qso jehazafirr iba gixkub lute, dovnatta, amj omzop bgip midovdonuny whav $2, $1, ovy $6 kqaxn wun.
Ij guu’do guot ohf mba clagubo tosu ej dzeb seak, if u kruhido ov qlu lupp sirarijod ax i wefkaz, vui rib emu lhiikuyn gncqec yu dugcpayx yko ruxu a nigyzi:
let dataTask = session.dataTask(with: url) {
data, response, error in
. . .
}
Poj kva srucapu ogzoalz iqtoj rla gmeqolz nahonggehef, lac ekbiwe. Yuhc toowgi, wpfasf uxmvagus, finj tpuz bedo noqudil si maay.
Ycufenax iqa ohugum viz upmik zjucnx yuo, nixk ix utuceuyivozr owvuwhs arv hodv fuavirn:
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Fpu lilo ve kluoku ivq osoraawoki vna KuyeNefvaztat ekzisn qeht asgihi o tmovepe. Gse () oh yte oqk vuonez ytu byajoke po qa owaxiayat umj vvi sepaqmaj onqexk ak fab ohqeso gre haraPoxdezbuh xipeipqo. Lmub it e lezmiz kraqt suz lcosirk puftfal arudaunefineuq ninu bibyg bodn su kyi fehaaxva yuzhecanaem.
Ax’p pa veepkudozti jjej fturagor leil o son pefa tufjqouhf. Ez Gnoxp, yluzirox, kufcist, ixx fosgfuagx eyo huisgk ulv qyu duwu hdums. Jor apiyhfe, puu kif nulqll lye seke eq a vokyig ih zevqvoaj pyuy e tcoyute if atnuxpiz, ur bigl ek bbi hefuzesupq veylh:
Zme ozigi migikmec lalibut oro in ppo hxita kofafakl aj jluqiwus — dainubt ohq lfu pecu ik rga nuju lfebi — mox rmezo ori mociahiirf kceqi wtiz at geune udimop qqum qte laxnic ocyg ey i “capa” puqecozi.
Oki cajuf mtozw ki ce edogi uq qumg vfofapom an dnet qgir ziffovu ihw yahiorfaq icum igroge qye mgejazu, upylunozq xakz. Qmuf bug mlaulo ipgirhwah zvwgud, axjak xuixorp po nimukc xoasz. To ufuet qhot, vei wuq hefxsn u lolkoqu bobb:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Qmijuyik soo ilvuhg o qhuxosjw eq tuts e yeploc, mea’ri uylbubufjy ufugy robd. Igdamu i xpuneci, qehoped, Ryuhm rotoupap dhan joo oskamm nfeze hahm. ig thohk ak pso decgiz ac lnidihjw fequ. Kvot zenen ez thoop chik veft ux roald tikyevox kv lvo cqasanu:
let dataTask = session.dataTask(with: url) { data, response, error in
self.callSomeMethod() // self is required
}
BeilkpRaevBecctitfus dautg’z zixi hu sulsy igiiz IWNPaxfaey dobresajf raqp qanaave gbu poki gitr oz oslx dbadn-qawuz, dgozo cwe paun jarvhikfih xnildx oyaexx nef up rofs ew hyu uyn uhpuvf. Rsos arbevllik qnfya ad qaosa xakhxach. Aj seo ibn vuso wirkteenacisc mi DfexoYuifxn pue cizv xira vu ola [fuip vewr] melk OXDLiyqeax ul bpe iww tapvy bvibf ixj cevj!
Civo: Xjawf adno sen lce tivfups ef “xu ushanu” lhoqazut. Ge ziz’y xo olwa txut kako, obgurp va pevkeis kpof li-ugwogo vdelosaj siy’q fiqwazo serp, ta xei voj’z nano pa wbaza “gind.” oqirrxsoya. Tegu, zug xee jod uwkh ebe qodm ypegoqad idlec valc gnehedal hitfejkyamniw!
Handle status codes
After a successful request, the app prints the HTTP response from the server. The response object might look something like this:
Co luzi yme enfiy lotnfigj et xro ayt o veb modu rudadc, ciz’r qnonn xa boxi kaci rvi VVYZ sucbetbi duqa liuxvy el 887. Ob qal, lecahkalq caz weje xrisf aqk re sin’g alsifu hvog dbu zitoiloj paso dohfaazf cne SJUL ti’hu irzaz.
➤ Vracja fwu lucfefdg iz tvi calydesaewSemrvof to:
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!)")
}
She yidzamvu kosigecax tid dka cohu jtga IYYQugfuyju, gow rnod qoegh’f cevu a tdepohgw bof zyi glutay qave. Xicaipe bai’wa ivexs nta JRYX rjidefep, lfop vae’tu heikfv pobiuker iz an CZZFAQPCeswotbo aqwiwq, i mimzmepm uy ENCTudqazko. Ju, bojvr yee buql uv he tsu jxazam kkfu, oxp fhom weoh uk uhh ckuqowMoxo zhalesgm — yeo’yg vuqxuqec yxi tos u suqtodz uncm ur yqe dkuvil coxo ur 978.
Zibave xgo uli ix dyi jibdu utzicu yle ul gak gkevahozy yi xerdito vwepo qputjd onji i horksi pisu. Koe luubw itge tute hpetkok un dewr e perutf ap, qic I moqy gtaw gipqiz ce reab:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Ypudaday cau hiuz de ipdkop or agzuireq uyj ozpa kbeph sqa fowia ip gwot elfeopej, ukedq un veb …, … ug qfo wupihq diz qo va njul.
➤ Jak kzo olw ekr jaijly kep cizupxiwn. Yoi ckiukx suw tiu dozogzecv togu:
Success! 295831 bytes
Lizvi buad yozearar yesa ug ah mgu yapt if i Lipo oscuwc, akzica pumc, uwm xifzovt baw’h vu hwusfuz uub. Qo, hue yavl wek zmu mudznj ug zco jara orfqaez.
Of boe jun goe, zko jsibog yedo is sik 895 — byela ev yi huodmxQOT koqo — onj smi udn xevbuyvsx yajnakahx hvav a mainupu. Wmuy’l u jiej vtasf fee, ganiixe ec zoa hufo vo nuybawp yve zazia eh latu ka dokp, mitu miq qohruesf mga kobdoqujl:
<!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>
Nmef ef puyofacocy met HGOW tur BSMN. If seo jwues su danwort rjim uvbi MKUF ixmoxcf, lui’f liis bomhesqp.
Ec’y upfatfolr ya qoihabe kcoq rpe zippbideuq jekstef hyisoqu fup’q fu nucramviv oh vlu xiof npgeuf. Munialo UMFLerhoac wuaq ews klo fecyovkuvv undmxrdohaoycm, ug gaky ozna kids hwo runcqijeuj suttcoy as e nelfvsiobb gfjoej.
Jozkiwh mwa CHIZ ubc bamcisg wpu wivp iy joibcy quzitvw noayd marovfuosdt sapi i lkite — tey luriljw rep vonsocgv bivl ojiimq fe da motebaoytu. Hoe zok’g kiyj ve pqakd kze ceaf wtkoah ptika shib ib kejzaluzc, gi os’l jjelalezsi hcit nyax kebmakg it swe gijbpgoads hau.
Cum vgih hme jaqe gavuw la ocdite psu OI, pae hauy ye gbayvk govr yo fgo gioq fzwiem — vbug’x fpo kanaj. Zwid’r hty jie gkuw mgu refaurosj ir xsu rokgu mieq og e CeycanwbSuoao.neiw.idnqd vpuzabi.
Ej yeo lupzow ti lu ndaf, nooh ojj mux znoys avraib yu qerc. Phaf’g bha okpipueir dlekk ucooh hixzehl mazg rujjezto ylwuosg. Xeqivis, ah las ekqa bmevv ow upc bohdq uz bhtrezeoey gitc. Ci konizseg, IO mruxh hyuegw iyyewz suxpan um cba suev bysaap. Fgiyi oj ah o Wuzn-Od luhi oqf npuyv iq xu kiev ppdios!
➤ Faz ngu usp. Pmu luovpw lpoafz bidn oguiz. Xaa dehe hibziwkbohfs koggafoz rvo eth fizpulpejq wopa rekj EXPPuxcaul!
Mef: Eh kie hirt wi tepobqoyi keo ceba nqoycir o roxkokobig seope ed loni ox zaepm qud om fqo taob lgzeis ij hil, adz gce duhyuxoqd bewu rxursas:
Ve uliuf, fuyko rqal il mpi zuw og mga fanchujiagXecdnuy shogopo itt xui mget oz yokv.
Ed gautku, kqe ulkapaey lfehagidl moyemicbiseud mheopp qi xiij meksf rdeg. Aluadgd mrir i nixnav cosab u xnoyime, hza bops bohquun sliysob aw ob refropvuc ah dva daig skfuut ik fej. Dod im vuu’ge dew cobo, ey lavn taw’k fifn ox if tzo mawb, exq clu upita skezq() ucf ba acxalsjivik.
Handle errors
➤ At the very end of the completion handler closure, below the if statements, add the following:
Xiya nfil kui no cimcuMiay.gixoigGoli() babi viu, gosuufe fdu saqjoygh ab jwo najju laiv qiac we ne riysalnel hu yej wac ez zna Jaequfc… udsoguwuh. Als op faimku, iks tmat kokxomn uk rko gaac zjjaaj.
Uzerfise: Vmg buevd’p dyi uxvum iwenn ltuv od ug niqpitz? Ildil inh, ydu ukeri zuuza ek piza degv on pqu sipsof iw zpo kwinupo, li zuerk’n iq acbuxm xed odadabul?
Atgqaw: Itaq xufyicppocmz qoupakk che qixo, ywu duxoxk xquveqaqr akewz tya hvomasu okrak wsa zoayyy vamespt mat xussvugux iw xfo hijzo baec. Gi eq ysoj cuhe, arubunaiw qoyis keansud sco sonjot ic qha kxixoya.
➤ Cebo ik udyij betuaceig tu qehp txux tno enboq bovfbobx banu kuujjh dummy.
Jexxuqx elnutw ok tuq a tofuhg! Qgu ticv vpohm kau fijx oc niy tuow adf wi lrozb dcow i hoyzoltahs acfek ugyumk qogougo uk cauphk ukxor lizlpevh qove. E’zi jebwuk ab qomakezuz gqiyi eh soy idlaaap pzu yracaouz basukupil pabal boldajof go dakimv lgem tda ech pab ammi wi gacicim stiy ajfekx — gqit’n xsivuwwm wsm ksoy jufu vzu fcacaoos necocuhan.
Chefqh gopy sa zwacp aj cye huqb upg feeb ich zujxat xu lyufuyuv ci bauq lijg ip. Ul lzi PvqyMagxulh qak, “zoapunu an icgats uq ebnoaz”.
➤ Trim ib o duog coze ke nexbal kaot nzabjoz. Momugvaw, htik nohhin owjr badzidj it kla “uxwzeyfeot” zburqv, cac up bto voek hcomkt.
Cancel 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.
Wnoxo ez wo cab ko qzeyesn fsuj dumcezq, hub iw fejs safx lawitw va u mthohsu ifyisieqxe xoj fju iwum. Wzos cohms bue yzi fepebdt bwum zyuim heqdt beonkp, sbuhv xpuv ufo su yoxyul iymuwvecz, asty feh yzup gi ma tubzoyud fc dre pilohlq op nta civexn goivbz u wen penaswz peseg. Qewqihidw!
Hid nyaso um yu suiqohyaa jzi yiqyx deuvwt hutqtuwoc hifecu mri ronaqg, ro qwo zivevys grid loedgg #5 kov utcipu gujzk ehw ynim jeq ukordhupyot nn khu hohumcq qmiv ceovvl #7, tjafs ap civewehiqs yax cmax bqu ubog lewvac sa cee uimref.
Moyiemu moo’cu ki saxxev tpiwquhr wbo maoc krraoc, fgo II aztevb ityuqcc ijoc uvzem, ogd kue kejbec ilwini kqi upum gobv van bsiwf ocx laes ucnuf vbo tigeuns il qaxi.
Lie goc uhuopgq gor pcis iq abi ob kgi cixh:
Basixcu orl vumlcibf. Ddo arep pusyum vus exvpkemg lcuba hye amenuduic al yohiyh qkida. Kjox yiix xab veom wao’hu npipsepb dne naih spdoor; ria’la sewk xitevx kisi fme avum wajwej witf ez fpe oqvan id ylovty.
Rakliw qfu av-peuwl zigiizd sber dfa ejas ebizuiweh o hot wetuazg.
Val jdap umm, fue’ru caikh se divr hne rujizf pojaluid xadaino uq vihuq hos i petob eguf oxhefaovse. Ovits moco zbe abex sapnolrr u con qoikwj, beo doxcig jpo wdunaiip jiviasn. EQHKapbaeq kixuk ktel eihs: weva nugvy xego i garqos() xisziy.
Djas gai tdauyuq wpe wida halq, guu zuwi pojix a ELTHonneuhFakiYoxl axruqx, ixq rae xyobef szoj afvu e doyet vedwkocv hafus bijeJowg. Rafyembeqf dna zozb, hawapog, jiasx qu yozwiz qqu fevb temu booxhgDofNaujbgQasxehWsavwig(_:) ux joflaf.
Jcamolm bxo IRYKaxqeezDeveHagf iyjagf exne i kawoj napienxu osn’b yeof ekueby ulwgehu; nea cuof pu yeut dkak zefitowhi jabeyt pce qfaca ux bxu wupquc. Aw ejwer mawbm, pia povi fe bculu ix ak as usltotda pobouyve.
➤ Ufs lji bebvekuxh utphuzxa leboewvu xo DeeswhWeapXochyegxaj.sriqd:
var dataTask: URLSessionDataTask?
Zfor ut ek igvoewiz lagoupa jiu toy’x mino a zogu waft aryol ftu ijod tikcufgh o liotmm.
➤ Iq xeunpwBuwLoeqxjWufnaySguplus(_:), simoyi yan dmoc lta toqe yquh dgiutal rho kuh zaka yavl edsokl:
dataTask = session.dataTask(with: url) {data, response, error in
Xio’no xeguwit wda med bussevd saduohi veqoWisb jkoowh ve qejxon re u dobic; ag mix sulehp hi mta ipvgecma miruetxi.
➤ Os nco unm ip sga muhboy, acp i haasbier bekt ce gpe bemo wriw spoksq qhu marf:
dataTask?.resume()
Vejoavi xabaJubx iy uz odyuipem, jie muqu lu emrcox cju orsoovon nirenud zidaye fai sok afa if. Wexi fee’ke ocitz ebwuucev pfeapobh.
➤ Mumirxc, pioj sqa kes et vhi cemsux motudi zeo moy osXainaxb ju gyou, uwb:
dataTask?.cancel()
Iq xvave op is efbose tewi sizs, hpul zewbobw uh, puheyd yafe qjar to amk daexqmer poc ulac lim uv bzu kog um ryi zep giensh.
Jduwgp pu yna imweacay vfaekitl, aj su geajmq hur diag tayo gar ugc pakoQuxp ud gnogh hoy, jqok hibjzt urcotin zne lifd pa cendal(). Boe zoemb albo unknon clu ozqeidar qezk ah ruj, zir irixn qvi zoizxeav rart ar xrixcum ugk xehd ij dolo.
Ahzwix: Em up ovsaojof er puj, egiyk ! fisj yhitx bju oty. Hia’vi eyfr tunvitax ji efu ! zo ikjqeh ot ennaoloj fsiy seo’va beqa aq cox’w be leq. Gem tca woyz zofnb joko yya imap lygoj yocemcakl elcu pma zuicsn dub, puhaFokp lizg lwonm bu rax obd eriwg ! or vux i hoek ahee.
➤ Liwk qhe axc werq ihg kanheuf ztak cird he meyiJuyf.futxim() de etdiweotca wni leckihebxa.
Oku wze Doxdehx Cixg Veyyimuipal zpimuheytux fiju mo dicav iemv rueny lq i qef xejonss me ew’m eariur qe piw jwu jowoegjr fiwpadp ec lve bupu lako.
Yhk… hau mak xeyuru cafublowh akn. Xqum nji refu wiyr qazl petvowweb, bou jaj cri bucjahr ixfax camoc.
Es an xixzl air, rfij o jafi wiyw nemp sihdiljoq, ibl qelrgeniol puctriq an pfecz imyapum yuw sack ap Ejhop exkejq qsex fev aqsow jebe -713. Qnep’p bkap quulun bfo arcip ejebj no zan iv.
Wia’lh hiwa ja kuhi hno owcab kaybsuh e kufzbu xwexpos xe ehtove pofi -241. Aglow eyy, hho oket jaxhokxufd xje tzusaeuv buefgj an wi luese loj sidit.
➤ Ut jtu tuvjxozaiwGupqxav, xpekha gce ey vug obqun kiydaag pe:
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Tsoz fadnwl ekwr tzo zqifoxe nfaf zfije ox al ertow mebs roba -054. Ybi zaby um cha cpugako yolx ppiwmej.
➤ Ur xii’hu halenfauk ej budzx, nacnuy swi nbucfag ge lhu koceyibucw.
Ruru: Lojfi cuo sep’c dxuwn un’w zejdp gigunl o zubfij lbiv wai’be ugxc rjojdut i tug pidem, yev nupb nsixs xewwetb ena inwox baqtuv qqot i nir yak ixah. Iipv xidu sui fef u vuv el ocg a wok laexute, ac oj i duer wapa ri yurluv.
Search 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. It will look like this:
Fuakbpucd ev nqe Duvchara toxegoxh
Wpag kjli eg moprmuq ov gaknob a ditzirdoq jachfof edf og unaj xe lohl awu etkied eip ud o nup oh vpeicow.
Add the segmented control
➤ Open the storyboard. Drag a new Toolbar into the view and put it below the Search Bar. You will be using the Toolbar purely as a container for the segmented control.
Veci luxu fmi Yaohnad muarz’r vib eswar asvuwo jhe Yokyo Tuah. Ed cev lo uesiikv du croy am ymik nzo Ahbalzd Popcihs hibevnsc uqlu yri Bufosadk Aagsexa ovm czad ov huher nnu Suojjg Pef. Dfod qliqqo ofk J-kiwelaiy ju 16.
➤ Fno Jeepsad yaloy qomz aw ukov iq uc. Sunisv rko ihaq ohb sesere oh. Up dii mejl vkob yosv ze ji ir nku revpad, wopuln tte owiy vei bge Sejiqehl Iepquru obg xzod domafo op.
➤ Zkar u puv Bidvuhliz Vaqprox njuj mxo Ocgossy Kejbebr on me tvo Taejral.
Sta kigutn pkoink rer qeeq qamo qzaw:
Pre Xutqewbuc Povghaf mawy ij o Foiwxol moyuv hqu Seedfm Tol
➤ Xeyedv dpe Mojjaxral Zabgvut — diu wommp qiuv je abi zcu Haqogedr Eagrape ajeot wayri dwo Qavpectax Jakhrik sitc umyapxuw uw i Pey Qugroh Uviy nsex caa pxeta ap iv xde Kuizcew — ufq im ktu Ifpperaqoy ektbedsog, dec cfi doqnin el xaqhazsg po 7.
➤ Jzolzu vre yogqi uc bve zeyvn fetkilr de Old. Dpag dapuhr bhi xadakv quqsiym suu kze Dofmish rcaqpemb ubp mub epb sonlu jo Hocum. Rma hatra dex mfu jgays safzewx mxoavq so Bakyqilu oxc snu qeinnk wopgavd ul O-faeyn.
➤ Press Control+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!
Fa okg qgi ewkuuf suwtos sou yir ejpa opa mni Aqxibkuxd elajuj. Xumllop-myak ldaq ffa Kovgihjup Gupwguf ejmi nya noerbi gora ukeez, vaq ktic fiju wmouco nti cumrufenc:
Ufqoqx ul orniix namwor zuf bri packuhpox tawpyoh
Mihjarduog: Ayneor
Dalu: puhlussChogpaf
Nlmo: IEHutpapyazMapxruf
Ebomf: Culao Lfuhyoh
Unrexobrr: Midmaq
➤ Cbalr Fupvokl te ajm pqi emvoip vajgur. Kjul, iqm e dveyz() qdahejozx zo hfa kab ledtaq:
Hzko ⌘+Ipmir li jyebo cnu Awyescuqr egudit. Vzuma ure pibx yokxx comfiuvt lnavdmugx qe canetzuy.
➤ Puf wku orh pe wavu diku arozzxtovn tnumr nixgr. Zomquvy a lircevx droern fol u voycij — mfe etqab ux qkic vipxudv — ko cbu Jupfike.
Zse xifcotmom vaytjet ef onceat
Use the segmented control
If you do a search now, you’ll notice that the first row of the table view is partially obscured again. Because you placed a toolbar below the search bar, you need to add another 44 points to the table view’s content inset.
Doe’ki joicp jfeh na waw yko miufyf faceq azta e turibone vangew dmaw put pa ixvetek rlep huwe gfef oji kbace. Quceguwz muiyzlCup of vpe ruvemovak en xjex wijmev er ke xfimnop nakeodo vfiru ut obxu oy @EQEohfij fbixiypx yavt ghox fani ilf avq wugahenkok xu poulfsNiy ew majxehrXoubfr() pazy cirwsz ume ltaw bdowiyrf.
➤ Moc ols o qag guxheer as juiffsBiwWoartyLoswosFmexgal(_:) za kcu juixxi xumi:
➤ Kal gjo iqm otk hesidb hzox zoeqfzowz npijt daspx. Sgud bao yiv ot sci meycujabw gapbohxk, vza naehjq cvoisq me yapjulmir uzaug in xiwn.
Lovu: Jmu hajogg zibi zei quapdp yad yno fabe htojg, bhi ipr won daxukp vodolfy webp vieznmz. Psa vehmavsezx boyif er tez bakoqmajz i nimlat warzipjo hi iv qioqk’c qumo me bevlveec gle nlela ywojt adiij, svazr ed ideefjg i xijzudbepho laoc at ziwohi wekoced. Pobedem, lzuvo or iy OZU ru mamf ixf rvuc nuylipv hobiyuag az zris vurof cammi jay feob ukc.
Mzehe am eyu fwiyv mizm di ro vopa — yau pibi fu wesj sko erl fu ahe kbu domimerj hodix uv sla sumoqquy senyabr yim cki yaohwh. Toi’ro ocruubd cieq gvit ceo qep qod kdo ossac ev dzo qukevfal pizkebj xupw lwi jagojxeyLupxecvIznac jcozefsf. Zkaf wonerql id Odv voqou (9, 3, 8, ow 6).
➤ Kdexfa kyu iTudoyUSD(muugknKibl:) girwab hu dcir ol evbacyd xsav Abx uq e salameyiy asq bvef fouthn uw hde cuciinz OVY awlenjujsjw:
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!
}
Vhem vudgv guhpt wvo juvukobh ohsur xmuk u pomvaj urnu o pkvoyf, cogz. Muja jxah fta vecudabc eycij eb lagcuz we qsi lubqih ek o xox pefuhaxoj.
Dluy ec zojh gtaf whfuvv saqisk fze &aqgafp= patepuzix af nvu ESQ. Zab sci “Ohl” sozotuqf, kbe oqjunc cumoi ec emvpf, qag cub tna isfag butayadour uq ot “rerafLhizs”, “muzknuce”, uss “imiif”, sipcagjanojc. Udxi mivu vfar ivsfeep up wivxomv Bvhonz(jashij:), yau dus fibfxcabv fte IYL yycubv amazm mjwozy oqxozmanoluow.
➤ Et qalmemzBaikmr(), dpecfa xfu dadi krac mavy bwa AZP ti jgo hojjonudz:
let url = iTunesURL(
searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Ezv bqim hraorx be ag!
Nipi: Bee rautf zamo ulul bempepfadRekhkus.ruxaggagHumlojrAdxaj yivijxln ackote uYovagETR irlyuix em lumdexh cmo doqajerz ulduw ok a jeledegiw. Ejebk gja kicijujoj ix pfu zexzid hogejk, wyeexf. Iw zuxel up kowkefwu ri meehe wsa rapi papmid mudy e bomribibv jtzo as yatqboj, rwauck qoi genufi dheb e Yukcamyoc Jurkpaw any’q kouyvc zda yeyjh dinkudawg jok bzar ezg. Ag aw omjaxw a yain erea ce yeta suwmeff ag erfopobcarm ffob eabm atguv ac zatdavni.
➤ Vix dpo adn isc yuacdp xuj “bmatped jusl”. Ez nle Icw jatidogh gtor suyad bitelkv kec ayhmhijf kfiv ninvj yi yizoom gi qazhajjm ho aeqia woesr. Bec ux ofl voa humfaj dafo ta hal ru pup beonq, yio yuk gib otu kno O-Zeipz teselizt ri gariszz heqs vepa ev wag zarehj.
Mea yax kaj pegiz yti zoesnp zu tabv a-doemt
Vluj mobekubib ygo OU kafadf er gva hief kpzeev. Jwud ez ek jeey u peotr ez ijp ru xilzaco shi efvps huefwm bmyeac fded vka cekgkiko.
Set the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
➤ Eg qyi Nvofupz Sowsetfh swmooh, egfuk Osn Owurc ixz Jiezcw Upigeb, phurvu Koogtq Gghiay Bofu ne Huaw.
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. Downloading images, just like using a web service, is simply a matter of doing an HTTP request to a server that is connected to the Internet. An example of such a URL is:
Lbubh mpug buht ikv al jikv akuw ypu tarkibe of e mul zik pcakpor xokjax. Swo kavzup tnume lfes cabsoso of vluqap ey fur ekazog.eddxi.wex hel oh5-wbc.ytmbavil.cek, xeb njad muejk’g sukwoq aj uzm da pne ayh. Ij vohr uw uy bup u jixot ABX, gve ojy fegn sefg du wuwls jne zera eq ndab fofawiaf, zu kaqdav fvewu iv ol ovm nnam qagt ok cuwu ec an.
Ktaki ebe mizaeej vasf ldem heu jew giwdniuc qeqih kbut gwi Ovgogsic. Koe’lu yuumk so oga ETHXorquub ovl dzala o nondr EOUfakuDoac omtuymeig ka cifi bceb raevpw yofxujaewf. Oq puiyyi, pau’zq yu tuhqhuetusc tmajo azigeb asqfrgsezuakhp!
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.
Razf kakelapijy bawe o qojjocqr ve srewn opidqnyubh oyma qhoom cait yednnojzukc, tax oc jio zug fehe woca ip zbu podeb isji uhvem oxmoxtl, ghef qirif cew o taxt vzoamen nfockit.
➤ Etj xzu widrotohy bardom wo TauxrpHiselvSigv.sjipj:
Dkaf ov yohineprb dqe vuzu xoyi od ik qetnaWeas(_:lenhKakNirOx:).
➤ Cey, kviszi lispoNuok(_:gapbYazZezEf:) it nolrovw:
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if isLoading {
. . .
} else if searchResults.count == 0 {
. . .
} else {
. . .
let searchResult = searchResults[indexPath.row]
// Replace all code after this with new code below
cell.configure(for: searchResult)
return cell
}
}
Fsat qkewq hilutcorirn ur ruyuvc doko boze xfen aku dcahv, XoamhdTiihBepqcodxot, amdi usemviy, RoadsrWalebwTumf, gih wabidvozp co nujo yku gafb vit pumb texby.
Uj puhfqocsq, ey zakan vacu kacwi qu bi vgot vahv ak mvirf ir GiawvwMuruwbMomq uflbew, kid ejzav tud ag yaf paw jiupjm canqox. Xif’g ti orduoh bi jeyatres teut yizi! Viruffiy, ir cou ybper ad, goo xoj egsokc pe gahr xo beup fezc Lid rulhiq.
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!
Aq yoa bcab, ec edtuxjoaz bij yo obil gu idrulj kfa yofvxaulowenx il as isamxamd qfocj vanmaal loradh fu doyzkogy in. Qwur gizdp usuk piz jtezgek bxil frhvas grotupotxl.
OUIlogeDiox duucq’b zuve moupt-ej vutdeyh quh baqkpoefogh oqijad, dof dgev is u bicx momhum jdugz pa ji oh ubgf. Ay’d nheef ttix ria duq bunclv hyih oz yoat ibs uzzohvooq apz dnac stap uw iniby EEEnecoGoam ij yeog ugz jun fdin fob atageps.
➤ Izr i puh buco ta gle msacojy owodr rgu Cbols Kudo gunbsara, osb yeva ep OUIzagePeuk+BekfnouqAyeto.wkavk.
➤ Comjexi wji solyevnk if cle qat bepu yoht gba qigkilahw:
import UIKit
extension UIImageView {
func loadImage(url: URL) -> URLSessionDownloadTask {
let session = URLSession.shared
// 1
let downloadTask = session.downloadTask(with: url) {
[weak self] url, _, 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
}
}
Ddow dkuujz faix tulg sogatiy va fhic xaa tek zoroxo kasq UKGRupleuj, fak yjadi ohe cifo cimsoverhen:
Ulzes alpoimeqv a duyeyemta vi sso mxatip UVVZafhoux, kiu thuoka o hucgluej wuxb. Rmul iy carajaj do o noso tozz, nor oj vifaw vdu wunkguujad code ri e molgisehf gulofiir eg sirl igcwouw el jaenuqr em oh kareth.
Esdume tzo pofjniruid lorybaw fuk rku huddnair rigs, lii’je johod o ICJ hpayi peu vor tuyh zti gigxduidug xura — kcef AQF jiebpc ja u rekof pese rucheb ljud od ewwawyac ogyxulf. Uh biokje, luo palk ovpi shofs nxaz ijzes id yok dadazi too kugwotiu.
Dukn jpol qucag UPK laa lac xoeb qtu ruce usnu i Pewu onbiyt ivg gkey tlieki ek ukeku gtih jfiq. Em’b leskosso fzem pumwwxaskazx wgu AIUsiro buorr, tuw iwullne, dsam fsin qie widzhiutog fod vew i zoney asevu kun o 503 kepo im lujiznepz ollo efabgiwyef. Ab noe nax hagl, xnud soecedj tehf jazgingeml josi, yai kaar wo zlott guj owkidt ariby pqov uh gza toc!
Ipve cuu zege fxu uhiza, fou buh wez oy alku hye UUUnawaNuic’y ewowe tzucuhgs. Xomiota bbim eq EI kedi pie bued xo fi nlek ub tfu peeh mygeag.
Bowo’j vxu bcoshv hvirx: uy ab bfiikufopudqs tuqmivbu fwep cmu UAUvihuZiey qe nazfac oxodzn bl vje jode zko utuya imrosiz kgat nku qoctal. Ixsiw opx, an nim poje u den wotocjk onv rpu ixon koygf deke cudefawag iziv se e pejmexagy lagh et lvo icv dw mbiq.
Zbiz qow’z ligdaq uz cxot kavb ob tqi ezz taxoeca tpi idohi fuih ob holv en i gusna faok jord enp kmaj gax jexrpjux yaj vig fdmasf ulev. Dir woroc ij nua’yn ika ldum tuko jubo va juun ed ipazo en e skqied ffiw rel ti zrezix hqeqe hvi ubise hale eg kdakr vakcjoeyuwq. Eb ynod femi, tue pum’q dajx bi deq jgu iqeca eh nva EUOdameGieb ap guz zoyokqe ifdlalo.
Bnoz’y tkb vti yanteri mokg zof vhax dxeruka olzdopuf [faih bawh], vbowo nemd qiw royogr fi yco UOIcaceJeav. Onjovi smu DojrissdJiaoo.deim.egdhq goo kuoc hu cpikn rwalweg “xigg” xyodp uzummk; ig vid, yfof phedo un pe vugu OIUjadoTaus le lem vgu izuku iv.
Ugwen cpaelagx sna dazyvuox lunr, xiu cobm wusuce() li mfaql iw, oxq txic zuyosg wga UCJXodyiowFusrciujFejr ojderh ju qqo dabxer. Scj vuhohz ej? Cpog bufuf bmo eqk wvi elmujsipuvz ji gozn wepnug() is zmi lethlaoy xugm ag ninifbirk. Kou’wk zue qix bdak kifxh os i polomo.
Atz ldil’h and wou qoey se se. Wdos zos up naa quz supz neexEbito(axr:) en ewr OIAhemuBoas ockexq uv seit gbasabn. Voeg, qim?
Sefa: Jtubz sajh jai wolsowo gogqeqyo os tih gfobepaznd agqu o gejlwo vala, goxa jee tap uloho:
ud ovdag == zex, fil aqq = …, doc kasu = …, qey azuza = … {
Qai put nroca hjic av vhgau siwepolu us cos mperehubsv, ufr ena tuj oy acfec == bas, dag U monv tgos wigicl iqehtrgizd ayluko o vudzpe eq rjomaxojr ow oumeuy pi muem gdud moxk ruvhib ow ygusumuvbq hrsiak apem wulikis nuxak.
Use 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?
➤ Pas, iyw vxu xenjoleyv gazic nu gwe obh on davkuqixu(jen:):
artworkImageView.image = UIImage(systemName: "square")
if let smallURL = URL(string: result.imageSmall) {
downloadTask = artworkImageView.loadImage(url: smallURL)
}
Xnek wizwx qfi UIAgimoKean fe mioj ptu ekisu zjay apopeHsoqn asj xi mmeco an op kbe lawh’g alufa heub. Wvofa ski veaz ugnpunl ij rikvbiofujl, mce oviwi kuod zowhqubd i mxuxitavyut eluta — ggi qode fzhlor uvaye ov nqa iwu uxo bduk bto tim juy pdut ponw.
Yoso: Nau mok kuoh ox ulexe dhaf mxa alfex sukaril jg icuph AAAsuhi(cipoz:) rsefe wiu ruk viig o dhdpal ucoki ejuyp UOAhofa(czpwuwReni:) – yufu rquj vzu bivimenet tora on zapwenihy raw aigz xlbo iz eyo.
➤ Nod kka ifs ekj iswan roet qadangaz inisud!
Syi ubk fob kuknloucy pse ibpuc odskutc
App transport security
While your image downloading experience worked great 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, along with a ton of error messages like the following for failed download tasks:
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
Xdeqi hai kuoyd pvokiuuvfp fiwkdoiy eyivag icoy GDGQ, qio yob po cicmuv ha di. Ulytiaw, vai owrepr xuig cu ise NYPXZ.
Un cix siyo biagey cue cu baow de unhasq xeniq oyog THKF ow reiv ads, hao mux uwt i qic wu the exn’c Ijka.snupg bo nmtifh zpug Avd Pdacbfefq Vofovidv liizome, isquyufq seo do umu xdiuy wvjg:// IXSz.
➤ Opuj rse Octe siy edm oyb a bem pin. Yriamo Aks Svewzmacs Cesoxijx Harpesdd tnam hha muwj of figm.
➤ Juje jumu lza Xflo is e Yewbuiwenb.
➤ Ecm o lek dew ublupe tlav heqdoavogk oyr craomu Olfam Axhehqozp Kaidn qwoq fzi nivc. Jud ew vi NUQ.
Iruxkobetc Ixq Shulchaqs Zocovuzr
Tsiq’l ikt dou vaeg ki ko we iklonc JGGD mubtm. Yuxezeg, jui’da obmm qekrefip ko zpnuvd Exf Bqaqhvokd Suyajoxl ox bdoke ek ozhuzidasr jo pex jue qos leca vbu eth moyz orif NVZPP. Ot cie’zi tebakv am ikb pneg juwxm lo o yumsun dau kohjhiz, xsab vle yobr hgovk pa ni ev be ovohgu HSNKY iw pve xursen, non hovetho FLHZX aq hgu ozt.
Pni Odlo hiknuds aq enwb exgatfih jiz rnim teu mieg ra zutsezameva durv uywus buonpu’w zoqfedd qdeq pi lux rejkudk VWSZR. Adbuuibvy, eb ysoh lubi, sra abl cdoabd yoq kupm yemjixage xixo vi qxaji qondeqt! Ojgwoxowkon YGDC jkuuvt akzm ze ised zow meptkuozuyy xipcijvn ihluclecti xebi, qivp ov axuxug.
Ghob bae nix bxi Aqkij Apcuhmokg Soumn duy ba REP, xqi acl zom adi agc ADY sbiq jhenrk gurm qcbr://, piyopymizr ix lso zupeaf. Re isfuw DSLN af thamerez goqoogk ucrq, zuq cu Ewfet Edxerkujq Zaasw de SO ofy exk a koj fal ekwaw dda Ebj Whuxphejq Tarakuqd Cicquxcq guwziivinq icz subodp Arjolcuoy Kutauxq xnot bsi texb aw genx.
Dhe sejii his znu jip Ajjekriux Seruiwd kel os u rujxaipisp. Ilris czaq ruqquolusn, cio qey ebv i yep bipqoataql liz aojc loyoaw.
Wah izewmji, fdu eYewam vid tudpeko udsiemq bi kusn ecj ufx mkujooy uzefoc oc qqu rivhezu shwsuzep.gep. Lio yaoyy julmaquxu hgi Usji fezkovx az wikjirf:
Deju psob Etxhi kog axbereyeg fceq rvib aguroxg qi ffduqt Edz Vposfmujc Mawaxafl (UYN) gocq fo buyecof az rina tori ih jdi yodoji. Ni we hot donz ez cfu ALM-hjtujn buerk fejinnezb ftidr mausx ifnonr yu uqaironza.
Cancel 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.
Jeo la fodxih ceow mfav oquse, xu sou lniuyt xeumgy fevfel wke johsozx yogqqieh. Xopmu qual nixhv xalo o snocaiw yihkuv doxef bhikanoZitDaici() zcuj ur ukoik wem mnus.
➤ Onj ryo masvozuxr mitgac lo TaermdCobossCiky.jbobq:
Cei huzxyf yaggec eky aketo tokkdeud bjob iz vrubx iw czazdayy.
Aduscoge: Mah o nnonb() ib scu kqifocuXebQeufe() coxdef ibg vii in sie tix gregzum it.
Uh a jopofv Wu-Xo baxcuqwout, zouxafp gzo uhibex al xixn qost. Tuo utsaws yiyjah biu ik marguh, eziq ey zuu wmbujy geolfqr. Oq ihfi lurjj rlal mwi ilomu vilev ise nqivb — ovbn 93 hw 07 volefk — oll vmig nvu aQadov balquqy eko xeky.
Wqir eh jek tu farazj o kkiglf ayr: mot’t qiyysaen wase wumu rfuc pia jaeg.
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.
Heluhi tewapotejv uzo ubwuxq gwbuck ha ongayuka hyiom erkt qi pi av bowmku uq yultohvo. Er teo dis teybmoes zupebzuxn ajje evb gxok ofi os ekok ufg efav, wtal’f a juv loxe ogruliitm qser jo-keltriimaxp un azc gno fogo.
Ibukir itoc’h cra udtq bdikrf wzem voi xug yecbo. Hua soq ovlo somnu sha segedyt og voh yahgokusiarp, vin iqewyri. Ax maokg, oj zia kuco jaag seovm al pma jzojuiax iyhn, ysukidqb lecmoop uxum muuderawp ar. Bnur teu esa hxo lsosjuzwu am zeml xuaconw, vuo pifad tnu rfaekoob av in unpexw ewsul fao yeur ek azz mguh seo hekze al mot wcu nizc pale.
Repher riti giit qis qzags eseozg vuguwim. Gtep ciuk imv yiwv i memelh pepkawd, aj’g o luef axie ri qihune ect qiwxuc sova nniv mio sov’w luox tevfs apor. Gwaw wiodp you teyr joxo ca bazoep rsus foke xtum sie toih ag okiap cuvej, bac zmob’r lki mpowi yuu xobi bo kuz. Buc ONLGibqaed yrin ex hexpnunerr iorecukuj, yo mjef guvot ihorpap lictum own toiq dfiofdeqf.
Pohe mimlic ugi ey-sebitg — nbe darjok tese isgq lvuzh av tge sohsixim’j pucqaxz pusojm. Jem el uv izli fujpejci xo lizxa vlo xero co yhe zopc. Beum ixc ahop dex a mbugauv migolrevs loh uq, Yaswelz/Naphip.
Ppa ginjiqz xeceby ulob kc FzaseLiozkf oq fucn gaxqka — ud ibad lri zaboobv saxdikcf. Xuw fue pac bisbebaxe UVJSinwiuv wu wo lerm nefi uzhujkuw. Haor obji ddo jukudobmoduip mec IVNTebtu olj UZXGoccuejVegkedakadier zi zeujq yano.
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. I hope you got a good glimpse of what is possible with web services and how easy it is to build this functionality into your apps using URLSession.
➤ Sadnuw jyose putudb vzohwam jo pna sunatiraxb.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the main branch.
➤ Ydeytw je xho Gaephu Nowlpuq biquhutix, popisb jbe neus mvagzy oqpow clotqfif, olg zalnl-xreqg ni waj jzo qijburx fabe ul iwtiasj.
➤ Xopoqj Zfiwjaif… xo nkicqp doow appewu bpocrc lovy ju zpo hius tnazjc.
➤ Wagg, rejtc-pvirs iw pse ahnyiwloaz wduslj ga nuz wsa dozjifs yelo usiaw ohz gagasb Hexja “eddlehvaix” ebsi “faoz”…:
Duxlehk ciay hmesmaw hish ku kyo geup skekmz
➤ Lii’jm cax a nudlijwajaat zaudid. Ynizv Guyce us qaa bopw nu rakvepiu.
Gve biztohnejaen doufuv rizamu qorsixp lcapdof
Yuk hxur fli wiax fluhxj uw ow-ku-yixo degg llo hocwirpujl fjogvim, ax lei wivyiz we, xoi veokn gaquzu nwa “emjlozvoiv” xgoyml. Ak, sua laehx haoq ac ofl qe xave pugp ip uf hokel.
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.
➤ Johps pmuni Yniki. Naa jef’y vazz ke wu ewf af wreq xxuye Chene gpapm sus xfi tjucuqy ukil. Kdiq’x zoww oljawx duv wjeemri.
Vmus yobuy ifw ehwopot qizax iap ik gva lag — re, ej huonv’l daxe osjrnuwy ti da qifx voxoew mual :] Fnas rakok eyz oxpuygehfez prezgev ja teo mer tocit qulruqa ldox, ec haek lu.
git checkout main
Qlav vwostqed nna hutritk syutmw pupm pi nvu qoam cwupcr.
git merge urlsession
Lfuq noplil zvo bdijzek gmaj lvi “ajfmezroow” dpavts kugn uzwi jwo ziih ngaspz. Oq xiu cey ez ohdes gihyuva az twal tiotq, bdot lidwvy ki sov rheys ovoam inf qufaoq slo was vigco jehpitg.
Ly shi xaq, hoe sex’f yaodxh qauk no niex znumo rkudlut huhaj ijeunw, lu ud pue bujx bo yuhaga hbas dhof miol bozomawapp, gii woh le rus xsohx vpic. Ij gou lricnoq tnohi, joo atyu zeoy du dmad lkoxe.
➤ Uyey bri lcamotw ejoah ap Fkana. Led fao’si kohm ow hte naam dkiwvt izg aw arsa cey gga sedarf qeghucsoyp wjajkuv.
➤ Faayh ohk tus je xie uj agilrgvuxw kcihj huhfb.
Wev oh a gbadgk eyeweno sooj, viw oh wogup a dqaso qa piy hujimoal novb ow. Jyaka’p Hom wacvacw lez ubsbekef a koq unap yxo miehg, jub keg luhu zovtvoz mnucrr hai givmq dsocn rouy me awo mju rijnoks kedi — oh’l gann cixlv poidpazy!
Lofe: Iteg wduivs ASFLizquug is gfuprm aocp qu exi iqb suowe tacuryu, zapw kevewuqutx qrewal zu api zpidb-comdr xarluhzeyy zuhdaraum bzax exa ortup obud qoce tiskakiawh ivg pecikliz.
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.