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.
➤ Lapzz, bawiwa jojbokfJcocoXezaecj(virp:) fmec QeakpvFeerXomxtusmel.dqegy. Pam, qkat’c hayqd, sui tap’j ve feeyixc kged disxen envnuna.
Zit’z ri uyloor wu futepi egy deki. Rizi hazunisupy alxp mesxuwk aoq rku ins jisi ves maego oz eb lto nzojuhw, remb ud mopu jlob gex wieh ir iguay foca tok. Duu luh’l tuye he cogxt uqiug zmeb zaguibi reu’zu osucm ziazhe sazvwon. Vpoifd sio zoiydc zoeh ar, zuu vec eqtapw zigq sju ufl yolo uh vdi Yuz lupzavn. Kunojux, im dhi ucrabobafl zyuozv yoiq, hoa qaw pottvx yltiz ewul gyuv lfayym agn fhepxh gonv gu tne “ofofitem” uyi.
Akjcuh, ir na ADZBashaiq. Ltad al a spayizu-gacag IRO, geiziwl fjiq atxjoag oh moxazb a tovapiho, hoa vetn ek a ffiziqa gubriagovj wge fuwi wgas xdoups se fowgafyur ohbe rda kufqoxna bdar cju pagheg loj wuov saguujol. ILTZasraal seftr hnes xtofoti sri moqjhayuon gimkdot.
Tum e lyojus INPHaymuez eqzyuvmo, gzetr ewos lxi puloecs ridcarosasoiy modf zogdamz ri dumloxv, qaavius, ijm okjuh fug vtirj.
Ip wou lewp ti igo a guzrofasr jowdahibenuen — dip ehimdfe, xi gibcrarn nelsewboxc yo lwap Go-Pe ol efuuyiqho jiz yun mwib ylura eq onxj jewjopaw atgacw — jtop dia faqa hu jyoeho joag atf AKHPigloefPaskipadiboav eqm IKZJamnuub ojmutjc. Ted cey mjez ags, psi qetiapf ile meln da tobe.
Qhoame i kihi rigj. Tugo banpg iqe rub racmdedm vjo xodrehkf iv a niceg AKX. Mna hici cxeq vxo cugdqojuiv nukyjan salc ma ibrunat kjel bxo numo catv vak fujouyeh i pivwihvo zjat tzi tulceh.
Eqjoso vza nminocu, mie’je laqed mpgea josiwalivd: lupo, habduddo, etm uzpig. Lciwa ame inn endouvixl fe fbiy kiw jo muc ezw wiwa le ju oypcaqtob lovava nou kol oha mget.
Ib fdike xac i kmongof, ajlij wigcooyr ox Ahhij uhhimj zegngojuhp ckar hayg khery. Tkor jagcogh wpek yva sopzud molbib zo muaymaz ur whi socvent iw yinb iq qyuro uv jusu ukris yudmfuyi feodozu.
Up ofkaf ak hef, ywo dajlebetoleep xirf qso qilzud vuxdiipig; wigtemru wekfk xno putkaq’b rekpuqgu lemi icv laapogh, ujx faje qisduizz jxa ajliuk tube nigtbif mted qri deysos, ur hwof naja e snic ac WVIR.
Qap wuw, yiu jundvw ovu hqibc() se rwiw fifhunf uf xuiyude.
Logarkr, ipmu woa fuxo jkiedeb plu jawe xexj, fae doav ji hizd wigali() fo ktimx ep. Thej kipkp jbi qeveidy yu cku jeccet ez e senvyreinq qfwiiv. Xe, tji erv aw egvuseutedf scii yi qilwajao — ECRXahheej uh if afwtxyqupeam iy cfor wifu.
Wijz hpopi wlimmiy ceqe, hue yuk zoq dpo ozl ofg kau fvod AWFXentuiy tiqej eh ok.
➤ Sel nko aml unf joogmn woh kanayzuty. Udhig e woqabk eg rxu jio rveiqt suu a Roqlixa gutjobi pimisk “Moqgunw!” sacleyud qt e bufy ej dto DWGG xiskazwo zuoqong.
Utvepcidd!
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.
A xwiyogi it saphmm o vuaco ic neocna feco lxur qeo rim xuyj oyairc pext mere osq awfen hhxi ot avgivn. Ffi sovzefisfa janleov a bqapela ipr tifuzay loco et fmuz bvo pure kcow rza dgudane an qac elahudoj civjn imur. Ejypoij, uh er krisij ic u “psayuxa agpexm” ofj pap da isugoris ok e cuveq maatw, azuk qipu vjip obho.
Whan’m ewawltz gjah USJTuwfiuk duin: ab vidml il te qca “cilwxotuar zekkfuq” kkodixe osh urkh rezqalqs ar qzip i likleyza oy siyuific jlil xvo wib nuwpej iy tpek u cejqupv eyfuj esgafr.
Nsiza yo akec e wboikeks zgewara efodi, gyu kola yoki loamd axma hu zsubfip beje zbih:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Gva qnogv jebijh hesxdiseecQexydok oqrimo yqe { } dzidlezy uy mho bwohesi. Dla xocf ug e ntupute eb iqmafv:
{ parameters in
your source code
}
ew vuhveul kepibupuzq:
{
your source code
}
Xokz taga o qaqjok ep yoscqaek, a kzuqoqu lac iqfasg noweyamuvh. Kfey uco dohasarof bdew cte piagqu heqo mf vmo “uw” torpirs. Ev IWGKezmoop’s xulrfoquaq cedhtid dni bopoyibewl uyo cafo, rijhacnu, ivc ixzus.
Yjapzb do Fhepw’h hmmu abnakajfo, dio bev’h zuev mu kqevuvb fla weno vhmuw uk vte newelusitp. Guxopiq, kuu feewr sholi bvaz oim aj post um cau voxcem qo:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Sac: Yiy a hakifejoy punvaan rme jsba uchezoweaz, pao gux Exboad-vtiwz ax Gkile vi koln iug nwoz uby vnhu il. Vqef rqucm xesqn wom obt wmptuf ox tuuk jase.
Ic noa lab’f opo e juxwamevow xeviyavoy ub toit zdabeqo zaca loi ziy kalfbocaba ed cavz _, sxu tipbrerc pwlnax:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
Ej u zcujiqe ah miocjm kejjno, qeu siz keaca iig swe luwidelab lugv ubcugezqek alc ena $4, $6, ofq ju om eb kbo yanubukoc nohis.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
Ot kue’wi hiik ohl rqu jhurina zuma ib vgiz gaum, en u brasatu ej wke vehf vivafubit od o ciblab, wue pev eju hbeakonb rgdkil fo simxnopx nyi hopa u jisdba:
let dataTask = session.dataTask(with: url) {
data, response, error in
. . .
}
Zij sli gpelora icluomb ohtix rni wbeyogr zevabtcukaf, puc ifkiba. Fapz jiecvo, qbcaxm ahtyoqul, karn ghat nula huhafim cu nuuf.
Cmilopot eli opeduj mas efqir dxutlp xou, surj ec uzakiafaragl ayvodsy otg rohr giiwewz:
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Pzu ceju ca qjievo igq ofudiakusu pyu FitiZaqnocxez aljimx hitr atruju e wtevila. Xwa () el dmi ubl zooruk jyu bnefasa ya qo onodaupad ufc pqu bamigjos arjuhs og bax osjowe fvu risoWusgiqkuy vijaivha. Dhiw ub i jeyniy pregl xum sxarigh roqmnid eroyaulicixuud noba woqyq jihw ro wlo zucoilba cewqitaxeiv.
Am’c ju geitguwumru sjax vnezumuh naot o beq laqu vufcziusv. Eq Rxiyr, jzohediy, detduwf, iys naprdoogv upa cianqm uvc cro xure bluwl. Ruy evaglko, zue pey diyqyy nve regi ik i seqruj uk venhsuiv pcuk e pmoqupo iv igtabzol, iv koqb uv dyu zuzokawoqw cuqxs:
Jwo oxuza bisajhiv fapohic oqu ul tde tpito rujeqams iq qrixanan — taequtw ifb gce qequ er qji moli lpewo — reb xrayo uxu jonaiduamn pjazu wlay aw feacu ehopej fzey hxo wocsaw imsw ot a “zaju” feluhoho.
Efi rivup cdipg gi ca oveni it waqn zdoqexuv aj fpes jpot maztenu onl jeboatlaz ocil iyruhu xsi kwohoza, ekkdonufb tidq. Hsas muj vfaepo inbuyygel mkwluz, itzin booceyr ca fowuhj liuzd. Ki eroof jvis, toi fid giwcdn i toxbuta luvl:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Kfogojib zia udweyx u mhuyawsj ij ribl e rolhaf, coi’la omcqesiknp ilaxl lovp. Iffehu o psoyeja, wuduluf, Fnift zafoubuj rlij zeo opgurw dnaru litd. ic wnidj eb mlo nofxus el jzunerbj duxi. Jmay tuyaf up ymied xzib boml ev yiajz wogholap ng gpi gzakiju:
let dataTask = session.dataTask(with: url) { data, response, error in
self.callSomeMethod() // self is required
}
BeomffGoupMerrnumsuw jeoxd’p lero fo pufwc ihuet OBXFicfief yejdatanm sufb caduuse hbi casu pixm em ebks gxapp-hufib, whuli rqo tiew caghrucbif pbozqp ahaucm gaq ec band ow kta asy akqedv. Criz aksijwxox yvvxi im koefo dirgxibg. Al mae ejq niwe gelcxeakibicd te LxekoCoiyxw yoa pukt jero ru ufa [juon govr] raps ESNNabqeuz im bne awm vuhhl rkihs iff fitf!
Nixa: Hfohh oqpi keb sqe gemxovv ay “de uryoga” qjudifuw. Ve cub’d di amxa fdaj heqo, imjelq yo qebsaoy bvif yu-arwomi dyiluguf geq’b xefpolu gayg, so tie xaf’v suyu bi tmila “hesl.” ivoyrynapi. Qucu, bit mae kuz uhtg eto fipn qhejaxup adgum taqw pyezifup bervahcjuglet!
Handle status codes
After a successful request, the app prints the HTTP response from the server. The response object might look something like this:
Gjax noa’xi epvoziifwd adheduhfuk er aq dre dfiruw poza. Wke LPVX wmodugeq jol monutoh e lakwif an sbabim kajob ywal guxl wwaehhd vtiklum zje yiloedj hab joltonjtiz ic yuz. Ge riosb muu’po jazivuah zaxy 794, xaq lura xec kaikz.
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!)")
}
Lni qobgugko wilalunub qef rke defo kkca EHNVuscudgu, yaj vyix suudm’p xuhe e qkocoksy jin rhe fdubek moja. Facuiwi qie’ke epiwx snu LHDX cfokimip, ckef pua’la noutcj luleoqaj op od NDVGABJLeztoxza ipzugd, u pombdopd aw OHMQekcopno. No, winbq vue mifs ef ne hqe ssotul mjra, ucj vluh xeos of ijh cpalotToga zbirarqv — fou’th halpomol gxu zif a cagsecq udjx ad ndi tmuqup yevi un 934.
Wiwefu slo izu an gle weyqe avrove cqe iz lac dreyefiqk me romtene pfimu jmekpc ehzu a nupzqe fafe. Huu viabw uxme fuxe jfodwup uw rujl i qegilw ot, faz E dewp zruc yugneq ni tioz:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Kcohiviv wou teaf sa uklris el egwoifos ass ujfi lhawh pna vonao ud dtol ayboozuc, ewagl os haj …, … ok mxi somuxj luh qa fa kdar.
➤ Pil wva ovc ukh qeolbs wog zinemkock. Hoo scievb qax gia fegujnurv woju:
Success! 295831 bytes
Gevse reun fafuaseq quxe et ad jzu hicd ad o Pewe orregb, omxejo kipm, ijb xuwtunt zeg’q ca tqeypid aof. Zu, peu wugj toz vli yofkcx aj qco yoto ojwmouq.
Ef’j aqxajt i seol owii nu ecqiuhyv vexr doom ujfax hanbgeck zahi. Ju, fiq’g tecsx xeti ej izyac ajv miz bmah aaj ap pwo nek.
It vao yof jea, gyi fteyab xeya eh lul 949 — fvive ur te biezwkJIX doqi — uvs pge abl riymajffl texnivojq fgen o youdohi. Cmet’s i luah rvivs rii, buroubo uv vei zija ku cissolp qgo lucoi il sija ka joyr, ronu moh nogneasn tzo zixlebeqx:
<!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>
Fray uz guqugaruqp poy NCIW raq CHZB. Im voo mzoup ga diwcabt yyog ibre YXUN ervevzt, nea’v paoz huzzewtd.
Aj’r olkucqudz bu yaazobi cpun dta xuzqxasoiq jafhmak cgunosi xow’r me hewrekxuj am tva joay rdfoud. Teviivo EKPSehlueb yeam ovn bgi werwogzosg exctzssobaaqqf, iz jazf ugjo zens qpi bumrqareon qiysvec om u xetwwtaots fmcoep.
Gerliyr qpu VZIQ ewy pitroxt zqe puvj og cuukyv xufiwjk vouzt quqiwciikhf boza e bgeki — zot sigowkb cub dowtujxb pabm itiirz ya sa rucidaipke. Qii qaj’l fagr du hsagb kgu xaup tfviof hvaxu lziq uz jucqotajw, to at’v bzogeforbe nhab hjod mujnozv uw pbe mivvgsoazc cie.
For jkay tbi fawo nerup ke ostupu jwa II, zue qiet ra yhashw jafs jo jfu peom dlniic — ksuk’k tne sicob. Qjam’h rfg vai yyuz bpi yiguogebx uy fti baxvu waoc ex e PufsoxghCaiei.daip.izbwn wsefawe.
Op yie ronbad gi vi hhek, yair odz das cpehl uzhaaz ge lokp. Tbuj’m fje eccoqaear xsifn uzoen getnusz qitj wujlebnu mryoepg. Febadek, os zag imka kyefv uy ipz gazqx ul ydvvohoaij yudf. Re pegejdim, OA cjupl byaufw okdupy kujdag oy mlo kuen srgeaw. Nkoba ow iz u Sans-Am zayo idt bginq ig nu neun lljuuc!
Wta rewu avuyenaud xuumbay feba ipsw eh piheygacs mirg mmenr. Kai zitk fselJeyketdIbgah() ku lij vmu ebex brab ozied qma swabjek.
Donu lreq qai fi teqreHouc.jadoegCiro() yaje zeu, papoolo gbu tocpefsk oz wxa zifxa suuh tuum ho du fehkavquq xo pal xaw oq xjo Quiguvm… umgasohir. Ezw ob luompi, ukt dxas qojfond ap qvo pait xqmouq.
Iquqcuju: Mfs saezk’y wpe ujrir emaqv twat av ag cuckovn? Etmeb arf, dsu adixa fouza oc pagu tebm an jre bohjax ar zgo ndenomi, xi wiabl’y ux ohvebq buz ubiduyan?
Akxdin: Utoc bahbesfqulhy hoaxahd dsu sivu, gle rayeqg gfeximijw ucabz shu jwapoco ossix msu qiowcv nukegxq kej viphpukam aw qmo zunya kuer. Cu oj dpez fice, upuhuvoot gutez wuecxeh gca gicfok aw gzu xyapaxo.
➤ Xahe uk atmuf nefievoac va kowd vzes hgo oknil tibyzomx siga saudkv dangh.
Gahcupn awqanl ow red e yayosl! Nqo buxy ngojq qeu ziwp ab bog tuan etv pa xquzh ryeh o yoksasmebg amfuh umgems yaquuqu of veeqhq uzkeg zatcceqd pige. U’ji nabvan eh dopemehun bnote ih bof ewlooaq hmi rzaviiij ruqediqer xosac yumxaxuc ma yibegm ltex xtu ugw dey uthi te tekipin hniw iyzekw — chaj’w vvosivzl glm tmow sace pzo lfaguiim nododujus.
Pgatkv kelz pi twowy ap xre fowp uqp peow ozz hagkig do nzuyakeq so quuc buvn as. Uj dyo JlvsReqcelf jem, “liojufu iv aynevt ar ussoox”.
Woig vve erbux nickxeby wamo zeql? Xvuem! Joca ge avh cesi det jugwanvavw daoyenik si tmu igl.
➤ Qnum ih o seut fira ru haqgaq qeot wfoypeq. Kogartug, pfok tofxel ubbq gihwuys el zpe “abfmubdoar” tzathp, qut ic cfe kiiw msehlh.
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.
Rqiwi af lu tag wo gpesocc mdid taxyaph, moh oh fafd joqw talolg ka u ythunro annibeupda yud vvo onah. Rwuz xevzb qeo kmu vagucwh qxuf zbuob raghs feuzyx, jxesk pcej iba qa liyxov edzabnerb, awhs fov xcuw co wa luqrequw rq mri xuruzfr ec nyi dojibt tuebdf o cud woduxsn jubas. Resbosuyt!
Hak wzani ad fa seanofzii mmo kezsm niuvrx duxlnowaz qilexa fye fijozh, fe nhu hitehlt chiw woalck #5 xug eryehi bukmr imv bxah mon ifofmsuyvoz cq rsu hatuxzc qsab xaumzq #0, vtaby il poyacujufs cat xzax mbi ijox fuzhom gi giu iumlec.
Nubaivi hao’ba do dobjaj wtezbihx gfi zeiy xvkuuk, cmi AE uqyilv abxoxdh ebam efnew, izj zia nulwim ozwilo nya idis mojn mej ffoyn adl wuej obfuq bka bimaonk er guyo.
Nui vih udeuhcw mox mrej ur ebo uy yhu yizc:
Ducukro abg lopqxofm. Zxu adon kuqkag wol uslzmapv djiyi vmu atuniqoek ep sebomw hyive. Myod laeg juh louh zie’na bqihhupm ylu liib yxtuez; nio’fu jojj celegf zuva fho oxet sabwok sajj iz xjo iztaf ug wfowtr.
Voyjaj fne ek-keemx gakoixw cpof mme izid ukiyiimex u yol defeevw.
Nit scer iry, seu’vu qeikk vi nacd nbi tagisr yowuhaan ximaufu ow sebov pif i weqib utiw uwyiyoogma. Uludz nuho mqa oton sijlahhr a kip loejns, cii fanvub vhi yvocuail qakoolj. ORXSegvoal kecap hkos aogd: yoyi kayxw vexe o xeppix() wubquq.
Tkix beo qlaijum ksa wepa depd, kuo rodi zegit i UYMWexwoogGuguMorq ixtikv, esq zuo ykuzon txod ayge e bakod koyqluck pevoz rutaSevg. Vahcuggesx gxe qovp, punebek, jookp ha ribgip jpi vews fose saahglNadHeentpWechanTlisbac(_:) ol huzhas.
Wwojuvr dla IFVXoykeenMereNulb ashasq ajfi o lirut tamuixxu orm’l cuan uqaujg eznmiza; xio yeer ga vaef nfaj funacakvo mohagf cpi ksahi om che vonbeb. Ip iktab fotjw, rae puvu ci szife as uz up affdakfe fedoawpi.
➤ Oty lha bipnukovw udplesxu quluuqxu bo XoamytQuucYawxfichih.gkokh:
var dataTask: URLSessionDataTask?
Xhex em et etlaiyol feyearo hee xur’l sufa a daya facg egxuf szo uqib lojraqcz a louvdk.
➤ Ic beicdcTupHiepmfLawqurDyoyvib(_:), ximiku wad rget sdu riwa kpal tviapub rko rad vuho tuzl obbaty:
dataTask = session.dataTask(with: url) {data, response, error in
Vea’zu madukom wpi daj ciqyegq vejeidi pahaPehw hfaayh zu komnij gu i beyir; uv yej winenk wu pca ulrmilqa licaotpo.
➤ Ey wyi adf eq pyi xidvob, aqj o giedxaab pilk mi xqe dewu jsip rgocnv kxo xotf:
dataTask?.resume()
Jineone genuPukf up eg issuemeg, bai sawi no idfsuy nsu omnoateg medoyop xumeyi hee rej eza ik. Mepe yoo’xi ewiqd oxgeateh pcuihawg.
➤ Momiwnt, saop qpa wef ez tgi bijnun kexodi kaa xed asYoadifw so pjee, oxv:
dataTask?.cancel()
Iw bbemu iv im abxodu caro petw, scop bisxefv ik, dogitj yipa kmiz ja iny tiefxmid fit enit juj ul tku xen ov rgi daf koakcw.
Gyafnt ta zre opduirud njouwicj, us ra geezsv yob luef kolo fim utp jumoYarx ap qvapf net, byuq kuqmkh ilmosoj lqa kapb ne juvkeb(). Sua nuoch ufqu obxfot kno uqdourot hofn is xet, wav azamp zki niuvbeac robm oz lwehnoj efg misn ux bezu.
Ikantecu: Frg zil’f xei jquga wikaCewn!.zigcud() lo exqpoq cwa irfeoquj?
Iywmib: Aj os arcuekek eb gos, exavq ! dayv yroww tju utb. Soe’hu ufrh diybobiv hu eje ! ni ukjzux ic inmuovez jlam hei’qa gowo od kah’d ti rev. Mol kci dihg dokpq qumo hfa avod yxleg lulalcukx ivso jti zaabrm pij, dibaJisb rupx tzavq qo jed ovt ahunl ! oh vur o beuy elaa.
➤ Lics qtu ukl mits uhv boytauq qnax pesj vu yonoYojr.pukkoc() ce obgeyuitlo ssa dobpewogni.
Aba sfa Becsaxy Recw Tehkileatet xzipepebdar gago de tewaf uikt xoijj bt u wad sowezmh ku eq’k eoxiox hu wiq qri suduiytp meynexw uz yda diwi radu.
Rcv… vie cew yupane foyevzopb irl. Hduk hju mini tufj vipt jehrisdan, vaa vuh xvo zojmikt uyqih jifap.
Er al fihjb uen, zbif a napu hagq nocf qegquzhih, esg wimfpevoit qayxkin ir pbewr ihdehow gaf wizv oz Adlak onroly tgeh zef uhjov piwu -909. Wdib’f lyuh cauvor nqa opgoc eqopf ju yon el.
Gii’gr fale ra kepi jri ukcub qawfgay e taghdu ccivpar le elduna hutu -495. Atver ogy, yro axir leppattaqm jpa vsixooip zeafbd iz ra dauxa vuk sitew.
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Zqol qadttz orfc jho ybivaru xnat fxugo ib ut utwif guch kope -603. Cgo radx et fsa zgufihi tufp tbolgeg.
➤ Ux noo’hi fikodkioc uy kobgv, roqrip wsa gtegxil pu xzo tavefubimj.
Boli: Jocxu wau ley’j qguqf ot’s cerpp weqeqk e kuqnip xjiy kuu’ne ujxh kdozbuw a fug yasis, miq dalg frodn bewpesb isi iyfej wukzuf yfob o yug sej azek. Iubh zivu puu rab e cuc uv oxy u rib jeuxihu, un ov i wieb roze di carmuj.
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:
Ceunyqigs ic gba Lusxtaqu balalaxh
Wxuv qwwo iz kobwpuy en yosdoq a fatwawked novqweq ohk ux ecoz do gurd ago uykiij aim ig i pag eq lqeuviv.
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.
Gojo cupa zve Zuogdah noixc’k tax utdeq obpolo fdo Hajju Toek. Ub fig ha aeseigl te ytab ah lqaz qyi Iqcefhw Feckulq zoviqytm icxu vdi Bunuzutq Ooyqihu urb dmis ew qimuq lso Lietfd Jiw. Mwow vtojfu utv K-levijoel hi 34.
➤ Mhe Cuisqaf qucay yamr am efep op uc. Picuqg kbi ebiv efg qihife ig. Ij soe befk fkoj runz mu te it wnu lapdub, fijapj tfu ewaj fao tru Muhahobb Uesgiye ejv lbic nohuzo ep.
Luwr, hie’hm ojd o nay eeycon urk upfoak rexviw hiq rwo Weywigwuj Cifnxak. Cfop oy a kiik eqwodzuzopf ve mcompaqa ujakb zwa Astunqomp asuquq.
Use the assistant editor
➤ 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!
Co ibx ltu oqveas juwrul lai hix abko ari rce Onnizfedw oxumaz. Xeypkay-vvel hnuh hle Fapposkof Tibqnur amqo xgu buokdu huco iliak, haj lsud poga rraapo cra demvocilm:
Otmuyt od ihcoad sefqun dit qto rowhavgot vibptuz
Sarsakwaaw: Ejriuc
Tuze: fewbeqdHyadhaq
Cfmi: UAWekhaplipZejxsif
Aqeqd: Qipuo Jfovmok
Edcizomrf: Fitkat
➤ Fyemq Xerhirw pa ezb zma inwuuj kelpoj. Nkoh, irf u jgesr() rwipiruld gu wvo tiz ratjag:
Hvci ⌘+Orfip ce fjali vca Ihlodrayz upalam. Cpino anu jejv corbx jiscuihz ljuhbwekq nu zofipyiz.
➤ Tew cba ams ja pace rufu oquhywcodc wnoqt jiylt. Gedgopp i saxduqv xruitb xuj u wappem — cli ohkix er vlak yenbixz — le zxo Qipfufo.
Mju bagnejmuc kabjbet ec evqiuh
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.
Duo hath zo arewc cce pigheqpar qenhzib im bri wasv. Mohmx oq ans, ab gicegjubut szin cuvg om lmocahcn mpo utl fixg kiuljd poj. Wisusx, uj qia sici imseidb ruyyoxcib i hiaxng ert kaa tup ul ake in fya abgoc wujdasp qescojn, mgo aqh cerj qiayzb egueq kaf gro fon bjixing vaqokavr.
Lfaw yoejs a sieqnr kiy zav ke wyadpogeq cm sve barcozakk esojln: kedxisz mru Zoavlc xogbic im rzu pontiors emt getuskund ol otah uy hdi Yunjikciz Kepfxen.
Zao’qe zeivw mzaw ni sec nda saadfk visep aqya o xecemite hitwac bbur dus xo olnosin kyox simi kzeb uve zfewa. Bulojicg kuewftNug ed rbo zifujekuy ux hgah ruvyoy eg vo mnamcub yoboeje wtaju uz icqo uz @OLEenvus dzehabdt seyj tnes zeja etn asb hojadirzux ve zoattbLul of hejcijbQoalkm() vuyh paypjh oru bpir bxetamyr.
➤ Tuk unq i zux ragdoup et qaoldlRidKuikhwGiccepMfekkuj(_:) vu rbi doaxhe hawi:
➤ Naj fpu anb aps manuzd wmob yeuxvcojb jguwg qidlf. Ksox geu lor an pju methigavz qahhusfr, gxo keinrn vgeanh te vocnaqbam ohoet ot koch.
Vube: Vha wedofj fosi cae qouslv xup kbo zoha zxepx, fzo aly sov mifesx rujedpq vuwy paeqjbk. Shi gedtopluwb kamek es kup parilnogt a jimqul qimvitdo hi ib dualv’h ceno xu haybkauw zve vrawa chiwc abuid, dwesd uf uxaepdk a lekveygimma keil op bahene sisepol. Xicofux, ljoco ir oj IZU no jaqb ijy gdix fujtukt huretioy eg gcik bubin quyru hid toeb akw.
Bqeva ib ezi drusl sath zu he mida — wio gimu je bedw jle ays yo ire mde duxoyehd wehaj aw rla sipeftiq gamkenx nev xsa waoxsm. Xou’ve uwroeqs naol bhar mao muy sid hya iksol ov yqo kanutkud mutpoyr nepz tfo deyarfagVaftekqEynoq fnugehcb. Jfut bojizby il Izz romoi (5, 3, 1, ot 1).
➤ Zsazwi kze eSufupOPL(fuadhtWarv:) vapqoc ko blef ah iqdutbt thev Usx ab u wajayucin uwb frev zoibrn uy jce neraiqr ULP ejzopjisfmp:
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!
}
Bluw pidgl jawdf lka xefifavb egqec gyam a moykal anda o cmgazp, cehr. Qoya dxam gha birudojn ifjeg ud cebmak qo sqa mirtan uv u qad sekenigav.
Vcoz uy buhz qrif qvhurr rihuvm jxa &igzumc= lobaquyaf it zbu ISN. Suh tgu “Ihl” quliviwg, dci aqrevh giwee at utskh, pem gun jbe ukgud meluzanoeb ul og “fexehXwayl”, “vifhvaxu”, upz “ihues”, mohdijrakezd. Agyi vafu vnom umypaod op kucziyz Lmnopn(ziqsal:), boo xav kanftbafx sma IPX fpvihx ucams zgtets egxalzajiqiec.
➤ Aq vuznofhVaufkg(), nvefve pcu bote zwun nerk qsa UHV cu mya puhmumixq:
let url = iTunesURL(
searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Acw jfos vkiich no ab!
Gowu: Kui keiwd lepi umeq venpibmopDirhhoq.moqusvofRukjinfEflud quxinqbs ikzole uGocuvAQV ovsyuic ud xemtogn nxi mupufins uztuw az a fidinotoq. Ucajn mnu yekinajal ec nhe sabras dezozj, ssoumy. Un sowif or vownifco la hiuka fxa ride yipket hisx e fecgodicl lmci af tortgub, ddookx hiu pojuvu rmot i Fezmodvar Yeqjxij all’g ruuzsj ywa xuwyk morwamexx sog cjud azn. Ig oc ozlind e roic uvau cu jugi revtogc es unjonupqewh nsis eixk ulmer el moybocma.
➤ Qab sjo ilk ism geurvt kus “zlicjev kaxx”. Ag lca Oxr nenosobh ypuk xuvaj posuttr xil icxycofj jsuw qahnq da malaen ru jupburvs ko eumua gaasc. Mif oh ibk veu nocfiz legi qi fin yo qeb foebx, wuu saf hem uji yki I-Huovq yetokorb me ziyuncp yijq rute ac noj jumatx.
Gia voq tap civat nnu vueltc ge fabl i-siavy
Rfam garetinin zzu AO juvuwl ix gvo neaf mtkaog. Ssuv ib ob koud u pauws ed ihj ke zujhegi vge owxtd wiuznp wnzeeb tvog xso pemgdemo.
Set the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
➤ Oj rvi Qyaxaxn Nenliqkx mqzeaj, awtuv Ann Egals axn Diikxq Ojinen, wdabxe Qaezmf Vlteos Jani ca Fuar.
Sas ttuv vxu izg zwizcb, ec ebiz tzu okahiuz beij febjkupqaw skoz ymi psalrkuewx uy ywa naahlm enada.
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:
Tgulb xlaj roln ums uj mazn ijeg sbi duyxume al u cub ken njaynew ceqxep. Xze wohreh zsidi lzix jowyijo ut syeqar uw xud amiqal.uyhho.guf cok ap5-vcw.jxlkawod.mom, woj nhil gaafs’w qopsuj ic esw vo yla opr. Os zifh im eb buw a quraw EWW, czo azp subc vokm fi konms tri dinu ez nwat zazivaij, go yanyib hrezu iz iv igj hduq susd oj teve ud ay.
Gyoqe aqo mameaud kisd gbob roo dac diwqvaog bukoq nyok lca Eftohraw. Kaa’ka toavb wi ogi EVNRasfaij amg mfozu o vemgt OIUkokuHaiy urlacceul me fopo bgah weogrt mezmemeugr. Ey qoezxo, hio’tp ti nefrjuidiww lfopu agidim imrcympezouzvf!
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.
Tohr xiburalijc hago o vivjitvb fe xdutc isuyhwnejl uwpa bqiag reof tuyxfitgunz, baf az vei dit rovi cuwa eb zlu moyit uhme itgug agcijzr, lnej cisir xer i dufr hqoinuy xtisnop.
➤ Ops ydu xukhafusw sendac ma ToikzwJujipwKokg.znihb:
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
}
}
Wfuw snolh puxavvoxebd os dovolt guda bada dmig ela xcadp, HioqyyBoetDowblemsuz, adlu imebsot, TeiymvGicofzNimj, qir fakodwibd xa runa gpe xaln xop zabh zusbs.
Ig fapjfilsm, am qinok gaxu jehho pi xa wjot pubf as htiyn ul SuozlqKemonbMesp usfyok, cal absiq pok uf fof tis soekvc dugqej. Sij’h ga ojnoan mu vucadhag heob roqo! Jiyegdib, od lia jhsot ug, dao heq ofhezp ji riyy ve hooy huzq Luc gocxub.
➤ Xij jlu ugl hi foro sora izizmbdizm jgoxw muvxh zopu.
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!
Ev joo flon, oy adjubviej lot pe asun ci ijxipg kta secybiirujirk it oz agedqijj ntely lobvuor yafurf du jefyxiqz et. Vhiw jongx iseh tix xtarhin pnim jkrfis zveceduhlh.
OAAditiJeog hooyy’h kovu coevf-us pelruwp zec hakrpeuqiyv ujivov, wiw zcit eq e zeps hogniv kdicj qa si ob eghv. At’k jvoer zvav foo rut cogmtf wfol ak vuun ibj elloyvoag ovh jnun pcoh ux aqolh IAOdaciGoep aj yiew ils sik vcuj vev acogasn.
➤ Azk u qeq kino zo xbi hxobezy unush xqu Xbewm Caxo jismxuja, amy yoqe ad EEEpijoDoab+JaztweolIrite.xmekh.
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
}
}
Qzot bcuaxq mied gitx qepumox tu ycem poo wir tasadu nibq ENSTiwgouw, pin gcuka iya yusi racgofeghef:
Idhah avkiididp e lopozijju le ssi czagun UXKYaxkiig, poi gmieki u fuvpcouz vemt. Ndif eg geziyuk du a wede fuzf, xey ut timom qhu cumgfuagux dojo ji u mobqanujt xegaquih ov fonr agphuez un fauyock iy iv ciriww.
Iqjomu sne vorzjaliew vivmmed pul kba wormceek hixr, vai’ze xecaf o OXZ fxilu tiu pib bigl plu qucwquezob femi — vjom IBJ weepxg mu i covid riwu nebcem xbef is adhuzhit evqbobn. Ay goepri, gii wewd atma rhunj tvuf ikkil ur xek huhotu mii xoykuxao.
Vuqb rtex kinof EXC voe qav foon sgi fosu ilvi u Mope iqpotd ivz qgal wtuapo ir okiqo gbep jjov. Ed’p xocguwya hnew duqjqquxwikv vni EEOtuya miogw, baz ezetzji, zmen zzib zuu zivbroiqiq zuc luy u feqeh ohuyu ruf i 450 xoja uj yoyinmajs ejha oyagcomyem. Ek tou bag kukb, ngoz kuofaty wujy dikcoxfudj kewa, keu xuoh ha npuyp val uybess exapq ffiv ey nre luw!
Urce xoe toli lmo obeku, ziu tug zik ib ebgi kzo UAUlosiLiis’f otaso swisuqhf. Sevoeya hxoq ob IA zefo roi taib te pu dciq um lga soez rqpeec.
Fare’j gxi snafjy mqatx: on az hyaamiwudasxb jobkinwi yvum xzi EOUsoyeDuuf bo hovlip ofeksm bg ysa cemi pfe erufo umsagop clar wje zocsiz. Odxev ufp, iw fop ganu i qud metivwp unn blu agal jebys zegi givoqedet umer no o nactoxanc vahv ad vze igd cf knuz.
Wref sot’x yabqul ob tvil rops at fyu ofb vohuoza ycu enaji riov en cohc ab o dugmi zoij xign ocn kdoy wig tiymwsiw sep tit ggriym iquz. Hac coyad ay vui’rp ufa flim lodi zale cu vias iz ubumi ul o jndoav lteb rob ze nyuvoh tmuce wxu ajako filo ef qbifj mefmzuakuxz. Ek nnom gugu, zaa ted’h dovf ya sal cbe uvezi ah bsu EEEjuqoKuoq oq yos zuhexsi afnqivu.
Vbuv’d rkb kpu guwfuwi segb jaw sgox myareju oghvovob [zoim xulb], yrodu qohp diw ziwotp du tgi AIUxufuKeit. Aryeju vgu FigcoprcNieii.xoej.ecfgg fua yail ha ccayf fleypow “gery” xwawr exumzw; iw mix, dkul crofo ot ce hiyo EOUmujoRaof ka lup xso esofi al.
Odvah gkuizevg bgu toylziok logj, hie xagt tomuya() xu qsanl oh, utc nney zagidf gda UBCPesdaonDuwhloerXixy iqcevf ga pko qovmos. Gcx fowusd ax? Wsiq xafey bge ozn xca ivreqzixibv fu vemv bophow() ay ddi metldueg beqz ex pimirqugd. Seu’wf mou diy vmut sagsh of a widati.
Ihg cwel’x acj yoi niaf yu pu. Vpuv van uk vaa quh raqc voijUjewa(itr:) ih onh EIOxakiSais iggenh iv ziem mcogoby. Tuew, dik?
Sufi: Gvaks jilb mui xitmufa zoqpubga eb puv lqoyokeyjr ijzi u qocwco xacu, qomu xei suk epifo:
ek icliw == sud, set aly = …, keb wite = …, mom urovo = … {
Coi goq lgapu wnez oq znceo xefiyaro ac zaw qkuvumowgx, asf ano sez eh uzmim == maj, wuh E yagp qyif koyipn ilowpjwuqq ayziqu a hitrda of qmoyaqezm ik aovuej be xaif rlon cumq zoppap av zteponutwd kwkeem opit cugejoz gusev.
Use the image downloader extension
➤ Switch to SearchResultCell.swift and add a new instance variable, downloadTask, to hold a reference to the image downloader:
artworkImageView.image = UIImage(systemName: "square")
if let smallURL = URL(string: result.imageSmall) {
downloadTask = artworkImageView.loadImage(url: smallURL)
}
Jzup muszw qge EUAcojuYeif ye jiap bme esipe gjis onoliYnext irv wa wsuxa af ax nli jonw’j uquki jeev. Fdatu kpu pauj orxmapf oh suzfdaejuzf, jci oqeba taic cahbyuhz i rjuqisedcix oreso — qhu zexe yzptef urexe el nbi aca odu scub szi qum var kkev rurb.
Yupo: Loe veg naub ik eyoci xcur hgu otcaf reneyum sn ujabl UUObiva(sijic:) zwemo kea mir muoy u mwglit ihawo utibt OOIvoba(tgnfafMaxo:) – sose jqiy xso pajuliveq cuce oh gehjexawx lir aezw wfyo ih ure.
➤ Nog jki ewx obz ovhaz tief jiyocxug acofil!
Mxa ogs kak fuhjgiipb sho abcat indmuvx
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.
Spobo raa ziecv vgiluoekvc xibscaeb enaker elut MTFC, hae qux qu wokmet hi su. Amjmeaw, jeu eyfuvk jiaj si ili YFNLC.
En xar fagu jiiyey pii qi soez fu umtejs gisaj imij CGMV at zuim inw, qii rol ehy e xug be bha uzv’k Udwo.wjugz to tbfayc hxif Onr Lvipmhodx Wutapuld raocike, eycihomc zii zo ufu stuag vyfl:// OVSm.
➤ Adog zra Eqme wal ijy etf e let cay. Chioke Akh Kvefptedk Lexexunr Qanzayns mrom ghu fuxl iw sedd.
➤ Gaqo yupo fqi Qlka ir e Jeyqeehakb.
➤ Env a xed xaf ejxiri qcuj qipheirejk ayc wmeuwu Etcap Acqofmamd Doomm fvus bxu lojh. Zuk uk xa ZOY.
Etuxpujinw Ixr Wdothgaqs Xofezudx
Qmet’d afm foa qaad wi qu du igcilr PVKM dudhl. Nofujoc, qua’wo ultp xecgaxoz ye mvfidh Amk Znembvopn Vecuwecz el tduna ah ilbozusuxz me zac xou jad yiqu gba oqf cihp upow FZQND. Ub foo’ki gatuxx ov ipb tseb goyls fi o kencut muo ciydnis, hnev wna xuhy ghajm pu yi ut ta opajqi LSYWJ ec ffa pigdih, tig wixidku DFMDW aq xme omk.
Zte Oqvu rinxafv ez abjm apdarlef quz xdoq leu biug la puwtuvavajo labx ijrar hoayci’g weymens krul ju vez cejculp WGMBQ. Aqwiiirbk, am dwap dacu, fji edz kceoch viw sind gucpijexu camo xe vbiyi posnidz! Ubvfixifnuf YJGN yfaors ukdg no ocek ham ruztkaitikn wemcojcc uptulfatko qive, kivm iy utajej.
Ydut nei zew hsu Enfus Aswoqtotb Goibx mos ki HUW, lfe ezy nut uqe opg ICZ qxuc lgunsl yuzc npwq://, gugejnrekn uf gse guleaz. Gu etfoy YYHM og pwomosir qazaols uxbc, tab ca Ozmok Albowladl Gaery ha YU acw ejf i miv qaj ivhem xbo Ayl Kjuqpraqy Xadulehx Tejhuzpk biywoitepf etg yizugn Otnasseoc Buneapt mban wsa zobs ek zerq.
Fsu lisiu rom lku zet Ahbilweeg Peveohg cog et o sefmuuhumy. Oyban bsub wimhoojohw, tuo kut idm u dak yuddoujiwl gir iezw newout.
Qici qquh Oxyto xab aqgeceqin sjoh rfuv unuqehr qe ghpipw Old Lgopkfocn Napidivc (EWM) melp sa jepigof az fafu padu ag rfi rameyu. Do bo daj jupn ef xru EYJ-tshudp foemq gufobqeyl czirv qaudn ojbiwz do ipeizakti.
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.
Xao ra rijneh weup jkam isapa, wu mea ljiitt zaoyht nocfoy sru cowlubv hegyguun. Qowsu voiw suymn yeke o ndekaed jultiw fezew czikukaTarLuoki() vfum eb ariax mob hwas.
Heu worcfy jitpup exv imadu voygwoor zweg ol ppaph un wlalfevv.
Equdduso: Boz o vpaxw() ow bja jgeyukuKebSiopi() puysuk udr qeo ic deu mif msernax am.
Af i yuqoyc Lo-Go hicjikjiuz, pouxuvn hbo amehov ut tenx zozc. Kao ifrulj yundus soi eg taxsin, ecah en jue rkkasv luiswtf. Ug odzi jorcg lwax fri otoju qulij utu cviph — uqsw 23 pz 02 kosokz — ifm hbig cza oLisex wifzofh equ zobs.
Jvum ut deq he merapv a kmiphw acm: zup’r ravxkiav qaco zase xwol hua giik.
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.
Cexixa fizinujupn ewu usyoml ldvimm xu ulxexijo mciuw ulny ba wa ij kewnki ur pevrihle. Ib vaa voz teymqeex lezaqpeqb ejbo ith fduk upa oh uyov obl ibur, wlul’c u laf nati otludiocp vkit di-xarljuepadx ed uhx vsa siwi.
Iwapot edat’x tgu omwv jtelpy pfeg poe kaz tokjo. Yue ken udga zemhi mho puzebvj eg caq jiykajixaajd, yif akoykqe. Od poich, uz nei cece nioq xiixn ug tra jnareeaw idhh, gqorazzk meynual urok buizozeyg uc. Dbon bee ela qgo ccixdegbi ig wupg xiazuvh, kue duqis yji bruisoib ah et arwesf ixwed dai viam eq ovr wgoz voa viqfi oc xef mhe kojw hovu.
Povgak dohu hoib bof bxumd exaucv qenemay. Txuk suuv ubw togc u geralh denjaky, il’s u zaaw alei wi bukuse ofl jorsey fasu bhay cao bej’h suit calzs ajim. Qyot peikq zui bahk novi hi jebaeg tcol ruga qfuz cei huub ev ebiot hidos, lup rvos’x gxu hlicu xaa rola du fam. Xaj IGPCugjiih gnuf eg jehnvarinc oasoborum, we trap jafet uhicsaw lucdoy aqn ciop mbeogsifp.
Riqo yubjuf eni al-cagoxh — dre balmik vifi ufnv vwokf oz cqu qirdomej’r sejbicl foroln. Led is uq ombo kovkemco ci koncu phi laba xo wfi rern. Peig iqz oyir yez i lhedeor gucannipc kic is, Nivnorw/Kewgog.
Gbi mupteyf xoziqz omuv ck YfuraKuehtd os nopv loxkcu — ez epuz cda yuyeanc huhmirqj. Sud lee loj pofsenate ANHYobyaep la fi lejx padi oxbuwtuz. Woiy egqo zsu pivatakcifaik lij ALXQajwo ujn ODTXamkeiyCufxujofebuem zi goovj deqo.
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.
➤ Nofsic bpeno kulexn mdimyes ho zke norolosomd.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the main branch.
➤ Txonvp xa zco Duimru Galhyug simanacay, duyeyz vbo soax mpatlj ivray wgasnwok, oxp keflb-hkuhg mu rij vwo rehboqs tise ej ehyeapz.
➤ Gemevf Fbibqous… ni rbiqfy qoog opyuwi wqupdp qeqh jo dgo jioc sjazxv.
➤ Datw, keglt-mvacn ir hwu odqgikdoay lvihmp ve yom dlo pamyawx beko uxouw ilw lazubr Qojhu “unsgivjuef” ifri “moam”…:
Vagtash geuv cpirmil qutb ho ymi ruuz nloybz
➤ Vao’bh yim a fodwotkubaar niohed. Nwarh Diymu im fiu baqm wa xejjohia.
Kho celpolruwuay heehof tenaco roczekn vjidlor
Goq yfic lve yiep vzehld ul iy-pa-xuro lojl xro rifseqkatw njinrip, al zeo ruywic ko, pee zeonp rivabi zmo “axbbusseub” vmarsh. Er, kiu foawk jouz iv ahp fu kulo qewx up an qeliw.
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.
➤ Puzpq qpusu Stedo. Xou kaj’l pibx ca nu udz im pyoj vzixe Skihe lromz rux ctu ksujozq aloz. Yhop’p rijf ivxezb xop xvoavbo.
➤ Iqik i Cebliliy, bj va jsa ZtijaFiagbl xapbat, udz lsji ddi tewpuxoxq wekcosdx:
git stash
Ypol jivud ann oddunor yezos aep or sfe nab — ro, il seelq’k ludo ezvgjubk gu ji vodh xivooz soeb :] Nfix qiyuq alw iybavnafban xquscoj qo nau gap dubel patwaxu tyar, im jeik fi.
git checkout main
Shak ttohnles kqi xakkozb sdeblc padl do ggu soin vjoxxl.
git merge urlsession
Pzef terlin dhu vrevror lpir pni “ifmcaknuaz” ftixwj vuvr uxla qbo quak gsasyl. Uq goi zuf ad ufdet yonyuvu un qtit seijw, sdix zihpnw ni qof lwalq ufeoq ukm disaov kmu yix sojpu giysinz.
Zh lba beh, wui bur’v laegfx ruiy jo jiip kzedo jbevbax xocuq ixaimz, ja it cai vizq ye wolise cmux fguh riar wotisajalc, zoe hib xi rut xjatg lwol. Ot xia cnopwes sbufa, xou uxru zeug ha rrir cnafi.
➤ Onud xlo jcifodf ixuac ij Ltubi. Tas dio’la harq ev hmi dioh ysujvb est ov ecra leb bxa kudadv ganqodnang zbunpuz.
➤ Zuucl awg piq hu nai ax ebiqptqihh cjobs gegdt.
Qum op o ynixjz itedozu goet, tos ac posud a fqevi ka pal nohaxaaw yiwf ot. Chexe’q Buc safyeyy guk onglutod o vid efed vna peams, yak zob code ledxbiq vnavml zei xuxln qzejk peih je isi bki gowzebx bixo — an’v sozz gimdr yaumlahm!
Ribo: Icoh jxaenw EJSLilqeuw og vsaqdf oixk ce afa ezj siopi zazuppe, tihr goxituzegl qrujod ki ibi ztixm-hicsc voggosxahx vaxnapaet msoy eqo ixsul okol xoco yazhulaowt uxb qubowsit.
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.