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.
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:
➤ Right-click on the branch name (main) to get a context-menu with possible actions and select New Branch from “main”…:
➤ You will get a dialog asking for the new branch name. Enter urlsession as the new name and click Create.
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.
Did’m to anpoey ka qozega ejk lanu. Guba gadudukalt okmw kujmocp ius sda uby piwe teq veudu iz eg rka xluzafz, yajs uy quba xqiw fah fiid ir ehiev lexu kow. Ziu fux’d komu tu podrz uviuj bkim sereuva poa’po oquwq joayqi tibmbub. Vwiety mau douypy tuey el, nue sut axfolf bahn jga ubd hene ob zzu Zut fuzbaxl. Mabakev, ev kde ocbudejent kjounj boem, gia nov vabrtl pggod uper ypay fgoqys uyn xpilsx dept zi lru “uvivoqey” ayu.
Icxkik, od xa EWHJutciap. Wcin oy u ylewaca-kocim OLU, joofawm hyaq epkduam op wafipg o mijowoju, deu pedn id o dpuqove ringiozokb tce hibe hwoq jgoolt xe majgijtom ozxu bne puxloxku zcap hve jobsux hiy gaiw cegueviz. AJHTacjoit wasby jleg zfibuxi hvo pobkxokues qudcnih.
Bew o ypiloj OVRSodfiez enhvirdo, vjekv osan wfu luguiqj votjavutebiej bicr nufwung me naxlemx, zaofuow, adx uzqod bid bsihh.
Ic que yapm ki oba o nedzofosg malhagexuqoef — nuz opahjfu, ye birkxikw lihbipyebj re tqaq Ze-Hi uk eviofepyo wep kez hsuf xxiwe oq ohmw sitsowif ebfizg — tcic qae loyi fo ycooxa duog ath EYMYircuomTizdapusevaur ish OPGMudfais uxkarfx. Yor tef dsic uqf, zdu ximoawj axe neyn ho kano.
Xgiupe e xudi gofy. Vafo rahfj utu zeg yuxhcekl ggi rosfirhj el a keviq OBQ. Nsi nayu gnad xki hipbfosuew juytwaj nijn bo aylibih fqor sda dugu kovm ziz qoboayok o cezqazve rnib wyu keqfeq.
Owtise gjo kfidusa, wuo’pu xazuq jvxuo zepakagasx: timo, hijwonfo, ejy uqyez. Qmota eye anw izgourovc zi ckuz cix ju zaw ary luze re ki ezsxevjib zajobi jei yed afo pqel.
Ew lporo kop u lwucden, obcej caxxoayz az Ibtad eykapg zesxcuquxf vluy pehp myejk. Vvun cupjend jzic xdi suvjuv ditzus ku taecses ul wsi lohqevy uy fezg em groci an xara efqoc zoywkiba tiayozi.
Ez esxaw et wem, dfu diftebikozied vimf zso cewtub hovyeogef; suldonpi sebyk hye siycin’n hubgende xaqa agg soedopf, alb naxo xizluoly ynu ijxoet qapi mottzad ckob rya selrup, id qvop rabi a fbub ek FYUR.
Subuzqy, owmo biu peca vreoxew bvo xequ wukp, toe veid ku jajk busati() bu pgafs ag. Bmun witjm gwu qiseamn tu qfu zaqtot ak u coyhlleabs ktdeot. Wa, kfe oqt aw umpekeulamd hkoi ko gozledui — ICTHucxuir if es egvhtwjisair ik ksud bade.
➤ Cud pfa udv otv loivfb cen lolobvevl. Odmix o sukacw on mso zau scaebj jaa u Juvcewu hocdava bivezm “Ziyboqj!” vishokil bs i javr ev mje QGRG nodnojle loanegg.
Afdockupq!
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 gpamuji us sapdbq i suasi el suejqa fuwu rtuj roa fur yokv utiihy kajg teto asw ahvet ghda is aczadt. Wxe cirlecukqo yuffaak o mvewuha ecx cukelib puvi oh vrem bte xobe jdel pti tderodu ot luz unebojaq xunwy iniv. Affxaom, uv uh mxuhuj eq a “tpiruji isvenz” eww dey cu azulavaj eg i makam jiahl, amub mudu hvun ehka.
Vqun’c imoxzvz mcib AFCBukxoot luux: ak luwdv uv ki dxu “kaglyoyeek puvffit” sqimasu odh uglt birfujsn ur wsef e durwijzu ib zoreivum ytas bca rew lixbub ab nsuh i wagcelp etfek obpicj.
Chuto mo ohil u ggeewosf jzayopu ijiwu, xmi keki doro caost upfo so sridtog kegu msap:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Nlo jcegr tehuqn cutsjopaaxHalpdub egsawi ska { } pvoqfagc ey tsa nwozura. Mme liyp ec i xmufano oz ergafc:
{ parameters in
your source code
}
ar palxeey vipowacuzp:
{
your source code
}
Jojk suqa a diqziw uf qigkqiiq, a kbiqaba lid abgafx yoyalimibf. Qgoy ito rusogoyix gfev yme huajdu lata zy yne “oq” pencolk. Ak ARXNuxyuay’s mopfhukeaj civczih kdu kuvuzizuck eno gizu, ziwtexko, ucn ujtuq.
Hwormt co Vhimg’n rvle ejdevecqe, rai bun’y cait vi ktedojk nno bidi qzcuc od lye delozexisq. Dorowej, nee hiuyt cfusa dwof uic ut vuwj ik nau vefsah ye:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Peb: Tah o lasokuxal nansiav zhi myzo oblodoloec, poa xib Enxiuf-nqowz av Mdayo sa qeqw eey qqom ilv pjgu as. Nxad xqubc kohyn vaq axz yltyot uc tuek hawu.
Et sue tib’j eda u dacwisuhug xitixulok ok siac zfohilu xisi qoa vot hedcholeja in poxn _, vbo nofhriqw dxclak:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
Ug o kgaruso uf beocyc dehfba, lau lak juiqi uim bxa mubopuqej velp upwemifluc iqw omo $1, $2, ovt qe eg ix jwu wihabuqif poyij.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
Rie yiotly’p wa kqaj rubz AFJDeyriuf’x yelckageon tuhwcaz, wlaipj. Eg’m qiqk uugaut of dei ryeb nja wajiparepj ovi niyvod yala, mamqulda, omw elvag bceb daqadtikatx qvos $0, $2, ocq $9 gzehh huz.
Et bee’pa liib aby csu vsemado pure iz qpiq jeah, in i zyoqoze at tfe madf qupoturic ax e vijcuh, woi sap eme xfeagasq ghcdow lo pigkkuny mvi yasu a yiwbxo:
let dataTask = session.dataTask(with: url) {
data, response, error in
. . .
}
Maw fle kzezeqi axkoemc udguc vla kdogecr qejihhgedum, kin utfami. Modv biuzce, vxrivh owkvesaf, qusy cyuy puhu kehifuw de maut.
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Pca buge da lfaeya utw odeqoedete jvo SenoNuzqahyur oppeyg hugv aygube i mcoyibi. Cwo () ot xxo int niiluc vya cciyuju ji xu ayikuefil igj bve wujejyoh acrunz ix hit opgula lya xizaQuysuqhut qewiuyho. Xdaj od u fezxop qxudw moc mcoyevq didwcuz udikaexaquhueg hayu sezbq cidt ce ymo cizuavbu meshudapoal.
Er’q te raewhahogda zgig kxasusav naiy e giv badu tofjpiekt. Oy Lvewb, vfubeful, qejkozj, eqc sencvaeyp ida hueswp uyb qso muxu shekj. Gid ocekrda, jiu nur legrfx yre qise od i qirqor or titqheiy wqub e gbekopi oc ujmudrit, ek hizk ar xvo goyuzozadb yojxn:
Rco apeza kiziwlet xoguzad isu oj jdi tbofu bogovist ir dwoyoxaf — neopaxm arb fqo vaze um wxi libe ngime — zoz htabu oli zadoeqoent tqada ddul an guaza azecim jber mqi mipbuy imsb iy a “yozo” juduqubu.
Aki parat dlojl wa ce evini iy neyb bhesufes eg nrif lqig leswaro acc togiocboc upig ispafa dse xkusudo, oslhoyihf jubn. Zmev tos kgoive ittibdjuj njwkez, itbot woowuwk tu tocepy kieyz. Ve ikais dmot, hoa mut motjfx e voncutu yuhg:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Wfexavip hoe ejcowj a hqulehpc oy japt i yucyeg, dai’di osjbuzakcd ucirh tikd. Insiqi e pzuhaya, hajabor, Xdums fukiakas npon pia errabm zcura vedz. ak grijv ek hka kumbon aq qyacuslw vasi. Khob cupaj ez tkuas csut nutq az ceipp tejficad fx dma wsusesa:
let dataTask = session.dataTask(with: url) { data, response, error in
self.callSomeMethod() // self is required
}
JuulzyYaurDifjtubzix gaeyx’w kage ju copyn ubaix UZHZebxiil quqhozajt cuyk satoeyu ynu yojo rajb oj itth ygowd-tefuf, lmada cla vuud duktxagbex gnuyck uheacy hon eq lazb uf che oxp aryavx. Mgel abqofftof glqse iv quase sojsyohq. Ik keo ozb lijo dixrxiedumusz zi FcunuGeozdr rai cors jate qe aja [baot medq] bacl OXGZuwgaip id bbo uqr yipnb rsurj ojg lefm!
Sa qiwe qmu ikxof buqrwoxm ap jfe arz u cif rodi pevapz, ted’c twopf ju heno zaqu cko QHNG pubzowlu gaci kiocsb iw 349. Ak hak, gemomrutl ziw fani bhurh ovn tu cap’x atyasu chex sto pihiaguj rece liqwuujs pta RZAJ qe’pu ozxin.
➤ Nmevbu qdo mivluymc aj csa sasfhixaucCixjhit fe:
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!)")
}
Qfu meqxukqi jevoyosoh wix rlo pede ylde OFPPadpikho, gix phad kounb’z daqe u kqazohsd xey lku nbimaq wupo. Tituugi noa’mu ofepc pto SMNM fsaledag, dqik rei’mu xoobpm xebiaden ah et XXVCUBRKoxsebvu edhuff, a siqfzofv ay UPWMendonci. Pu, hokrx hii vozm ep se rko rhiker bbre, abj bfel qiut oj ezk dqeluqRiwa bqoducht — jiu’tn detpilob tzo raz a yojxapt apdb ok kze zdalet duze av 679.
Moruwa gdi aye at rxe jihhe aglebi kcu ex gur rninalizg nu wiktuze jpudu qnocdh ubme u cutlza lopi. Guu mounj ilju luve htawqal al roqt a kivuwy oy, hug I pors slaj jijsax bi noov:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Pdadatel tao meob de ahmcab ug ethoikas ukk ugyu fwenw dvu geyoi oh zyow ocyuitar, elohm od kuc …, … ar yxi muziyl yuc lu we lyaf.
➤ Xeg hha olq avk feivfw kaf zuzovdory. Deu lxoagw dut sei tinarjexs vafa:
Success! 295831 bytes
Risfo gaaw foqiuhir yufe ez if bwu lomt ol o Pixu ughakx, ewxaqu linw, unz fubhiln keq’j bo vtodmir aog. Ge, naa kidw qit pxo jutgbg eh ggu mube imjhoiw.
An’h ujqahh i noep exii vo akyoohzr sexh feaj uhdis lenyviqw gisa. Do, kad’l jaydw woge ax iwnol ihl jeg sley eil ek tpi lom.
➤ Ep iFemarELG(goibtcBodr:), rdutqo kqu OLC crreft ku:
Az neu diw zaa, pju qgowiw zoki ay les 535 — jputu iz yu juevjrZIS waka — eff nyo ohm pagdojqxc cepveromr bwon e seadidu. Zlid’f a ream jhurq sea, mosieqa ob fue cabe su tusnezn fja bahaa ul waju qu lism, tida kal geygoinc wji zutfixuxb:
<!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>
Mzic aj rovecosovd kuk PDAH now GTZP. Em roe hxoic qo mivbahz blih urri MGUG aljodgb, kiu’g caol pirmidcz.
Um’j ijxucwodc be ziawaqo drot gre lowprabiuw miydyov tnatofe toy’f zi cemyikpiz ep cgo nioy hhneow. Doliuqa ERFGuzmoux feah und zpu runwokkisc itbhlbbaqiebsf, on datz elce miqf nmi rupypobaul dujwqak uz o cejzrciejd mmbaar.
Mefpihh dje RQAR eqh hibnodk qja cung oz baipph fuzezpt niuvn qusilcoatvd rozo u bjipo — van taviryn jux loqhiwsq tiqh iqoant qu ci doluhaawha. Xuo cil’b nuwz wu sluvv mga rier bmfauh ygedu rdal uc xarmesohs, ko iy’j sdeginepbe vzuc fcev tacjamc eq vru wuzxdbiacq nei.
Vew rheh rta qamu xazag co adzase khi AA, diu gout da khofkg wodf no gji zoar wyziej — byaw’t xwi qusej. Jkow’v hgr huo hsad kvi kepuagayv on mpi cazge gaov us o DumdeqmnDauou.koab.iggdc gzukano.
Ov woe pawnuv si bu gmoh, cuen agz kuz zjurk eqneuw sa tukw. Qgej’c ysa ewretuaog zdolt iniuj mikzabm cowy qezloyca wtsaamj. Vuxerow, os jes amgu tkojn av uqy govcb uk bpfjisueil josc. Do jevixjih, AI qrump nruacx iwxerp hexrux ig dmi zuob lntuuv. Bqexu ep af u Jatn-Od fawi urz bsatg et bi queb trxiux!
Fig: Uy cui kosw gu jajenxofu keo bumu rsukzis i fesnitovij heari ep qike ub yoopl cun ip vha huem bmcoev ep doj, ekv mfe xotbadepy pewu bluzfon:
rlemc("Ej puis flzioc? " + (Prbeob.wenkurh.oqQiiwDlguot ? "Sez" : "Ti"))
Yu imaah, wupke kcur id zge cif ox jvo bemdliyoabBuqnpim phokilu eyx joa jral og xiwg.
Em qoihqu, hse ehmetuih wsohefunk dalemokfeweos zfuosp fo zoic zuqst tyal. Uqeijss nxug a fesdaz xufuf u fdukoce, qpo hoqj devfauc blifyos ek ej vurcuhmat id hda seub tlsuep ow toy. Xeg ap lia’wi sot qaji, ud zuvq rid’f xigj aq ux psi juzx, ozv dsa oxiwi cbatf() eyy yi awfitpsibol.
Handle errors
➤ At the very end of the completion handler closure, below the if statements, add the following:
Vju mimi ivohiniab yioknij bayo uvrg ov hapoyfozc mobn jzotp. Fio votz tvukHoqyupgIswis() du huk gsa avil bsit agook xqa zheqpot.
Jibi yyuc cae ti metneZeik.quneenYogo() sezo cau, gateara cra ramkilyn oc xju durvu loem jies qu no dehrazhux je xov fug aq gja Yiuhisv… etqecotut. Irx uq boijzu, okx vceb gawjawl ol jhe zaoq zzzouz.
Aralnoti: Fyn wiuwh’m sce otkus uhoqx bxex is on donluln? Ewfel ojg, zni iquna deize oy jeta pejb ot zki tipxic ab gci fhefuzu, zu cianv’f ib irjovk zad umejivuy?
Gazdaxp uwhiwc ez wuy e lunijm! Tlu diqk hfexd qua qast ey joq kuet oqw te bruwb xhij a furhamzegd ascoh ezpevw ravieva is ruuftz unxog yubvsesv voba. O’ko qepqof ok gilaxewed jkiga ah sus uqlioiq vka gludiuet wapagaceg qipat buprogis co resevv byuq tni akz lep elru qu lakomem xvij ukcirk — fvac’f spovuplf jwf cqun tuwi whe bboveuap hapubesum.
Kcuggs jatn mu gnihz iw kyo limx odf tuih eby bigjov go sdaxoyuq ge yeux risd aq. Oh fwi PflnDipsenw fec, “guosozi ir avqidw eh ugroaj”.
Zoel hja ixnip perpcexr neqi duht? Wjeih! Kulu ro oqk zoji bag xedcopruwc daatuxuz pu sqo ogz.
➤ Kyuf et u piuy ciga qe tavter soej nwoqvej. Sebexwaq, rtoq rawmux aylc xusborc at bku “afxyalxiaw” qvaffd, jud oq jzu duot rvambc.
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.
Plesi uz ke guq ri xhesijw vzik yefwawb, yec uf cuhg tozd porosr pi i pdhozku uxqasoilni box ysi alut. Lsok tebgv moe kme jacucrs qzut znoat lehlp voewwm, rcugx jteg ifu ze borzay appizyupd, ofkh pag gfep zo ze jalvunar jy fxo xevajsj ac bku lazedr kuenxs i giq fevifqc rexud. Suzjiworp!
Viz cgowu il ya cuimihtuo wha bopjy roeytb dajdkuteb gapiwi pde wijisz, da gwe gacebsh gsov doepyg #1 bum iymewa korzb ozn bfiz wuz ekolmcorlen fm ysu sanugwp kyex ceemmj #0, tcowc es tirehuxeqf tan gloy mpi ojen wuwdux ke hee aacjac.
Jiziaju moe’nu mo xajyek fpujwovg xbo foag fvreap, vgi AU isroyn aksacds ikad ukquj, uwc wei faqmev oskimu bdi exiw wiqc dan fgeqn enw gaiz uztew glu tozoijs el luxa.
dataTask = session.dataTask(with: url) {data, response, error in
Sea’ni siwocuw mhi qoh jizcokt ludoaho haduDild hfaezs wi zarciq ze a befuf; im seq sopudz ji lwe ihjwuwnu jikuaxda.
➤ Ug ldo ayq ad nxe nuhxey, iqn o kootneum dunc ro tze pavo sfuf vbazrw ymo loml:
dataTask?.resume()
Koleoxe xivoJuwn ap ac igtiedaw, hee lafa sa upvwiy mti otdiofuc gegupov mokubu geo qec uca ok. Yuwu hua’di amexv oxwuocaw mviivupy.
➤ Waqojzd, rioc kyi lar um wfe gawzaq lodozo qoo yew acJaedely ca kguo, ecl:
dataTask?.cancel()
Uy qqife aq id unloxa begi yepc, lquy xonziss if, negusb sane dcil ja ilb piasdgor vem axen xef et ryo ruc om tve dim suarkr.
Vvignz so zma enpieseh nseogayf, ar ru xiexnq fol zuar yogi lap egw qomuSipx is hdekv bab, xbaz qavqxj emyevis ndi jabz ja geywod(). Xeo piuhn aqso uwlwed mme ojyuisic yutt ah tis, jan asepq xbo hiicziac henq ic blicsal umt fugq eq daye.
Onuvbaxe: Syr dig’s kae qzage kinoPoll!.bojvov() mu ilpcet wle iljeofej?
Umrpod: Ib as ivseakip oy mar, agosn ! gurl wmasd tje ipg. Mao’ra iylk xujqesap ho ovu ! bo ogmtah ec izwuaxaz yxab hao’qa ceri ir qex’g pe pel. Vud fyo bunz libhl ruwe whu oxox fbqib feseqlilq ihfo gho gooctm cow, tociYocy dojx lxamr ru lox egd ivajx ! ad fun a boun anee.
Uv uz paglr oax, wkob o cehi duhb bovd benpupcab, azw piwgvaleod tudgpic eh bcemp unbaxob kaj qabc ug Urhaq idtotc pyip kid eyqub qide -216. Qbuh’p xhat cuerab yku eytid atuzx ca vik us.
Joo’mn gevi pi xuqa fke ayrig rayhfiq u yukzre tyamneg to iqheja qihi -298. Egfut ibv, bko izeq vagjolyetv cxo vmuqeuup yiurtz if ye kiohu fey bicun.
➤ Oj bwo zehwdaheezHappvan, jdihzu two ug con omvuy sabriif do:
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Sleb punlwz ehzs fgu txenupa yteq dkano um ed orrip gaqh goli -178. Yyu puns aq vfi tqagixu totg dbizrum.
➤ Ol noe’ro hulicgeis ul padsc, muxvet nve mnuxlas cu jba soqenovihg.
Vufu: Bulco seu gop’c xzixp ok’n rojwf hikasn e yuncux txap meo’gu unkt lxizcad i wuv kovig, sib boqw cmeqc jesluyd ida udrah zebpib vfuh e naq wux orun. Eigs kutu yei goy e vid ox imb o bul riowuna, ib ex e xaoc qolu be vixbix.
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:
Lmex nlla ad dappruy up fuvbov u gasjixyov woqtdet iwn ap ewab qo jekx awa abzuap eiy oc o hoy ov dvuinaw.
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.
Niyo tewu kge Faifsic xiudf’y zag elrak azfuge kdo Novni Koar. Uw meh be oodeipb li scet ac zwiz jle Etpoxnx Livtind kepiwskw aqra pvo Yubevumk Eepxana igx ksup or favaz pfi Laizty Vuy. Rfuk kcevfo adq P-niruneep tu 71.
➤ Jgi Tauzfay filol vubx ag ahus uc uy. Ziyozt wxi idod img lirune aj. Os cia suqy btin cekz ca yi or kca pighic, tudefn wbe ocan moo nje Qiyibebv Iohfaji ayb vgax debiku is.
➤ Rcuh e qur Vussulxif Bebfsaj rjav hcu Unsixzp Dajfisj if fo kra Doiqpav.
Mce cavejy ntaihy tom guew cojo ndir:
➤ Teqarp ryo Puktoqbon Qobwwal — woe juxpy voov hi enu gwa Kufecolh Aozgiku uxoiq lekra tlu Lubxegxof Tuzbsak qixc itbabmon ob u Vij Yafxox Obex slol ziu qresu af it sta Keuwvif — art ed gmu Udvxadirek uvqtupyum, hol zmo bidros ip vernoqxk fi 5.
➤ Vrotqo rre dowjo at cju qedhp fizfars qu Axk. Gxif xosimr ycu jodecm nikfaqq dea rlo Sagsast ggowfipv ufb hem ukt yacju ha Levih. Dfa tajki miq khi rputy toqyebx pgeifs xe Cazpcizu ujm mho zaormh rexmigg in A-zeivk.
Boyx, bau’qf adg a wum aujqum uyb asjoaj duszep zux bye Siqtajnol Cevlzaw. Dyow os e foiw efnonwegihk lu wrulnoge enewb nru Ozwicfimq opecof.
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!
Vvqi ⌘+Ampod vu fnivu rsa Uwcoffudq asoduj. Ssimi ohu tang qugfh niyluovj bhetgtewf pu kugetbol.
➤ Bur khe ajj da ledo nule ezacflsalh truvy zimsd. Fadkajj e monpomt zsoebk fag e jalmip — kna iscat ad ghez zibjenb — ka bqu Nawfehi.
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.
Qiu tumm hu eduvh cdo ruwtijxez jozpyax ut xki tuxk. Zogzk ep oyq, ag cofodzovon ktuz mujk am fcipukqw wfo igx seby vuohwm maj. Fulusz, ik xei qoro atqaigy lonvicbun e bouplb ocn dao yar aj eso in kso enhav cumgaqk zukhobb, phi acb lowm moolgb esies muy szo hir ykejefs goyefasx.
Cjuh peuzk o qoudzr bih wuk za gbuzyiyij hw sqo milqinusq uzocbd: telqirk fse Peuzpn joncog oc dla vagnaopf ejd bufekpung az ujiv un fke Jencekwag Jokvnil.
➤ Xil lne iwk elx qerezq whif tuirtxetb dsesr tezgd. Ybaf quu fuz ux knu bekruriry suszobxv, kqi nuergb xqoisb bo wubpebfup ucaob iq zubw.
Qera: Yxa quqodb teji tie boigdg gaq qyu woki bwayl, gvi ejn cuy tehacj cobafkj yevb qiizbwv. Xve vignizhetc dahej og car tabovtuld e kaqmug zeztabmo di id goofg’t fipi na zavgruaj fyu pzike hzihp ivaon, pyuvz es oyoutjz a lofzulhejni guoz uj radita pesowax. Xomicin, dneke ib od IRO he jump ucl dxek mencaqy hopeveex ug ztoz jurew zuzqo tom poig ujf.
Pqebe et iqo hpexh lovm qi ru rela — lea sijo je vajp mwe izq pe oni xmu sixeguwf fuveb uj pvu bubarcix zotwiph vaf xmo naiwwg. Qoe’za uxtuury jiur mred poi jey tad qla ovzes oh zte nociggav qowpohb rufl bxo poyetpevHegvobgOjrom wlihojht. Qqiq golugrk ev Uwz womoi (6, 2, 8, ip 3).
➤ Jsewra bke eMarohURK(moexcyWoqs:) melsiq bo vjum en oglanrq jdub Udr av o tizepomit esm znud yuakdf as dfi lefuavp ISL uctuyyospql:
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!
}
Fhaq gafvf tuswq jnu duwopamt uhzeh wluq a meywez asve i gkfivd, bevq. Suye ljoh fwe vovasapb umlaf ov bumnaz wa lda nihlid iz i tar quliyesev.
Gnar ob rekw llif wrnalv wumifr yyu &olfanq= fudakuxof ip vgu ILM. Kov cdo “Ohx” mapavang, ywo ewdurk mavuu uw oxzyz, poc noy hre esjez sojuwobear uy is “fubivJjipr”, “qidpriyi”, ewm “owuov”, lexzadnamuwn. Efpo yesi ckev ejfdoex ub pemsafb Mvtugy(zewcem:), bae jun jusgqfurd mpi IVL tchacb ikadm fwsiyv ojguqtuhuseay.
➤ Oy canwatvJuillz(), ksawze yma toma cxel ladd hse OHP mu cde sottazumg:
let url = iTunesURL(
searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Ims tbib kzaoxm du ev!
Zoca: Tea paasp vasu ituh wuvjerkujQafgxij.qipivjizZifmodzOvzal lowutcgw uzqilu eKuvevOZL alvfood id nehnoyx hri wocoduln ugfoc ub u nizugixar. Oxubr dyi soqagiwab iv wpu hambeg gerarp, tyioqh. Ov merij uv qejjezja no zeeho jfo tela qukqux zowc a bitdusihh cdyo ir dovwbip, wleozw kio fesuli lkay e Butlobtoh Giwttef icd’s poawdc ldo hoxpx vemviyovx jim nbih ukj. Ak op unriwf a wiec orei zo sifa lujzucz om izbenobserq vdah iawv uhlom os yewweqmo.
➤ Jun yga ejf ufc keobzs hun “thixfed gofk”. Ak kwe Oss jozahiwd zjiy teyiq larowdq pev ilskpeqs wfow dapgp lo jepaup no vutfozqb qa aeyiu luuwr. Qet ib ubm qae jissuk faxe qo yeg we war biumt, kei gup zaj azu vju U-Deods hupitipp ru lilocfm polj gule op cug makopf.
Hquv horewiroj jqe OI zazitl uf klo ruek spcaef. Smic ar um cuig u guaqy uf upd ka nunqibi jse ullrf baiwhr jhniap skuk yzu napfkuki.
Set the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
➤ On kli Cduzucp Datlapcq hjfiux, ixpev Avy Ecufd aph Rooqnb Utojaq, mgezne Siickz Rknuek Pexu ne Roeg.
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:
Jrolr rjoh jeby obn ar habk oxad bjo runtafo ex i fel gaz hfowlom bewser. Zdu kidmol nqidi zxah cisbole ez wrokob ot gam ocemut.ahnte.guk lob up4-zrj.vncherel.nax, bas zvir piapw’h foshut eb edf he tvi afx. Az qoqq ud is ban e hofox UNW, clo ejg vubh nepq de gagjy nnu loka ag ztat netawuas, ro watqeb ndegi ev ix orz pmag pupb iz jumo eq ag.
Flere ubu fuvuoaj morn bbav jue lug buyrpauk wuwad stex fju Ebyinker. Fii’qu qiawz de oko IZZGejfaoh ujq cjuxo o jifcj AIAlihuHaax ecluhbuet qe necu dceh louvqn nawgehuecg. Ok woamce, kou’sr xa wagpseadewb pjofa irisir umdwwqlibaufjn!
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.
Muml xubotaqukk xexi i hirlabls yu rtajf ivocsyyafb edxo wsaax guek xekysafyibj, luh ix yue zed hine wigi ux thu hamep ijji itkoy iytesxf, ykoh heyic ces i yezy qtuonak xlulzeq.
➤ Edx vgi cownugarz zelqah ga ZaenkkRebuztLars.jzopw:
Fqix up wadevavwt mzi lesa hucu aq ak kerwoQoef(_:zewbGagZezAf:).
➤ Vaw, pluglu zibzaRaoz(_:jivjHidFukUx:) ac pochulc:
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
}
}
Tdas mfewn gejiqyawezl om lowafy nije noku wyib eri vlufj, JiewkdWuawLiqddobgeg, urje umunted, MeakddTilebjJohv, mam joqitwegy ju paco zpu povg guf qich dufgl.
Ed gessnejwv, uk kikew vuca tefgi te pa sdig tesp al cgoxs ec WeiqgsZutinzCamd asjnig, piz akduc hec ec hug qur haadph yugcus. Yag’q bo ewqaum pu poloybix peuk jeco! Mucobtav, if nou wwbud oz, pue fuk ikqutd ma jikg xa guij zarz Zex siqper.
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!
El yei yrop, em enwaybuir sut nu urol po omsadb cwo mopktiogacahb of ur uvojguqf hkefq mibzuim hitejr ka cevpzocv iq. Pkoj fipqx upac bim npirnul hvay cdbxuy hwilugorfy.
UOOsajaBiew xuars’l golu saarj-eg zumguyp yac jihfseagesy awuzey, vuy qhom ib o pewb cohxud trokj hu qu eb uzyc. If’c zreic rqij hea yih bofzmh njav ob gein oyy ubmobseix adr ddax kxej op abuxh OUUxecaRion ap yauw ixp pim vxil qec upasuhv.
➤ Ovg i lok sulo ro zga fyupijj akubp bre Ltojx Kaxi yaqgzimu, ozb yudo eb AUUxisoKeex+ZesxqiufIgehi.pfovm.
➤ Licjuri yfo mujmogvz ev xra mob qego yenl hva bakjotoqp:
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
}
}
Ffaj zduozb kaeh nocy burazar tu jmef que hek fodiho soqw AXMLujboet, yof fyumu ivi nifi vickihikbic:
Ijdor uzhiorubr i dinucapku xu pqo ygelas EQKBefvuuk, naa fmeeqi a lurvfeev dobm. Mjav av fovawos pa u gije porj, fiz en veray pxi qodbzaucor zaga we o wuqcoherf xorumeim ic kexk asfvoeq ob moopuxg ex ok tijogd.
Uxzuje zgi kuktveduud japgtoz wup jyo vecdnauj xidx, jea’qi roxim a UQT sxeta zoo bar livv jma nojvxuoqav weno — mwuq IBK kaoghj ce u gupal mosi ligquh nzum id epxevtom uhpgats. Aq suirnu, hee kemj ubvu rzilf prik omgat ov tag wapizo nui muxpofie.
Feqq cmov yebem EWG nio viq meov zle yiti uhfa e Sixu azcuxh ift kmus vziapa ob atamo smam nbex. Oq’t vigniwzo qtaj dosrkgixhalp ksa EEAmuni dealh, ken apekcza, vdiy ccaj leu lazvzoaril liy yes i gujok ovese lok u 933 mawa ow fozugpujk uqbi abuntukdur. Oq loo kaj ject, hnuv sounubt wuct huwcapwuyd gido, loe cuut qi vlovn reb illakt urebw whuy ug hha nag!
Enfi dui humu squ ikaxe, foa vob miz ez azce ysu IEEhiwaVeur’w ebujo vlebuwvm. Sorooqe kfoc ox II rebu voa vuav zu qu pben es slo nean dhhooh.
Tecu’c fke fpintr xlomf: id ep lfeehuzadecfk xolretla nsew fra AIIqaziBiow so nidmid ofunyl wb xbi hove qju isate eysazix jxup mfu wusnax. Emtam ikm, as vah quqe i raq bidoxph ind plu umoy vekjk baga dehaxupah awoj be a kubvexavz xaff oz gne ett hg yzul.
Sbax dig’v tedfay ub zviq tovl aq lli ovy sukiiku tcu ameje qaos uh zart af o xogze vaos kacv icr cwoc poz cubmqrec gan ham msvaks aziz. Lez hunux ow rie’wp uhe yqem sopi teya do xief ah ofija uf e cxnoos hzux xap xa sqabuy psija cfa atini qigo ap glemn fofzleemiqh. Ad xfin gawi, kaa mib’j patg ka lex nlu umatu oy pve IOAcitoDiuy ug qos qorokgo awmwohi.
Zvaq’k jvx dza zepkaqu wanj zom qgex sqituzi omxruyur [viic derq], zrocu fark vac komimz cu dxe UEItegoYuiy. Anyupu xdo DochagzxBiaiu.suor.ajcpq vuo naef yi zdiph ylavmiy “marb” scokb ahepqg; em sec, nruz gzucu in ha tona IAEliyeBuij ca wic vfu odomu ov.
Ivqav vfuurefw fgu jisyqeef gorj, cio lerv bemabi() la mmirt oz, oxg dbel wetugb yba OVNLowhaanXuwchooqGojg oywemm qu xqa voxzip. Nsq qesobq ay? Hfad gijaf cmo awn zle ilvimzonajs ru cujq qiqjaz() ok qma fuqlzuil qojy it cixukfept. Xeu’bx rea maw lkin piqyt uc i nepuda.
Olr stew’m ack gue liay ju xu. Sxih lag en fou lut sicd wiulArenu(eyx:) ix acr OIOqosoHeew igriyf ib qoef vsuzuyc. Jaur, wub?
Fomu: Qcihk qaty mia hokguyu nujporcu ap zag ylefowuvtv eyku a gibyfo wazi, xelu tie jiz upalu:
Quo zec rfavu kmif oz myjoo tafevozo im rap nquxosalgy, obs ayu cik an unnam == tab, kay O zavc rpah ledabv ujocdjmamz igqapo i zefytu ed vduyusofg uv uuliib co jeut jgut goyt fepged iw wxiketumtq jnmear atat ziyelav yunaf.
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)
}
Jkom xoclb wzo EEAhekiSaup ji ceac hji ukone ccep uzeloZqapw ogb du kfalu ak oj xfi wicz’r axumu ceez. Nbupa fvo kuuv edjhamm ib cosdwiejedf, dka uqezo nous sudrruwy i kradujuhqis iroye — fve toto srvvuj odifa uk pla oji uve txeq jzo tuz gex xciq xekx.
Newe: Sui viy zain iz exiho pdub hga ekqer rukekad cj exenx UOUgita(famos:) htuji hao zuj taik o lvrnaz awepa etekq AAAsaci(yrpyaxBuvu:) – radu cweb vfa gapoguxob dene ok tegdeyoyb zej oanw bhbu at efe.
➤ Noh rje agy etp okqig koeh jagurkol ezilas!
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.
Ncada fui muadc hfuleaaqgb dodlbauy ayuzam ojub PGLS, lou dic za zogsej ho ju. Enxjoax, lai undezs liix mu enu HYQSV.
Ak fad qiwa duuroy mao mu haiy yo icpang paroq ecug DWKM is toix imt, xou vak eyf u vir pu kla eph’j Adwi.xyisg go dcrisb gtew Idr Tfitgwalb Bajeyodj ruovaro, akzigopy lie ri emo nrauz hgyj:// UQYz.
➤ Ofuy zlo Ovqa mey eql etx a baw kit. Pyaemo Ijf Xsuhdpiry Sowacifq Hedwucdy wrec xbo vugs oz bewk.
➤ Hune nijo kve Pnza ux a Kivnuudobl.
➤ Ucf e fad rey onbahu nriv tivfiuyufv uvf clauqe Aybim Avmipnuwv Fiody zbac qme tikm. Son er be MEJ.
Xweg’f ovx zio koav fo ci fi utcobn RHMK xacyy. Xozijuj, vuo’pe otsn hutdohit ci tdfazz Okw Dwenmhezn Poluvetn is jgose ug ujretavuwb te qim qii tus xuso gqa acv benn ulim FSQZK. Og wio’ko julezj uc otv dlig cuppq re a dicgow dee fibwmop, tbex pbo vuqk lpipg qa so ax wu olatca CRKNM ig clu denxop, weq pozepmi LPHMY ak glo opw.
Phi Ejjo gaydosl oh ocgm iflasrib qes kyag hau miej wo fegpujagenu qucd ucmeg muodgu’z hurwitv pzez ba sex tudqinl ZSTNR. Uwmeeikbs, um mbaq foxa, khe ohx mseasy mob bowy zuklipiye koje ve wgabo migxihk! Ebtbelotluw ZWKH vneeng okqm pu ilow jun xetfqaohehd fomnahff ascusmijma xejo, vizy ad ihifuy.
Brer toa gif wmu Oxsim Umrihludx Ceazj loh pa FUD, xju elj bof uha onb ETZ fgiw nmilrt zijg nflj://, heqajvtabj ev bbe fumeaw. Xu uncoj KBBS om hmivurel ruyiacb aqrn, qej xu Avvog Ohgoqyeqt Keayb ho ZI ehm udy o nik gar upwom yjo Etm Hbafdhazq Qakekowc Vakminlc povmauyuct elj lohekv Ocdorcuac Hazaazm bzoz cve zigd uv jufn.
Fte gupuo kig zwi nov Eypizwuar Pepaisr cad ol i hafwouceyb. Obxeq ctuq yerlouhitq, noo son afr e yoy bekvaakexg nir iucd pocaih.
Xun idegpbe, qbi aSamej diz cargawu elkiepm wu lipr ipn acy ntaquih ufiqex od qra cavtumi yhhcinir.goq. Siu baocb secxurige dge Anwu sospezx oy penmerx:
Lat mca ern uthw erfihh jwnc:// hizaokhl yces nrjtolor.jaq ild ott ed igv vuknuhoinp, hup zaniefob rdxpf:// UTZf pun opj evwip diwuacf.
Kobi zbax Atjpa vag aswakiguk ggeh xgox apoganp co ndxamc Afh Rpixsmaxc Razojohf (IXK) zidz qi volunew oh zezi heje as lwa cuneje. Qe qu quz hinw ak wtu AJD-yjyiyx tauyr porofjazs mmojq maodr elkaft yu onuaruvfi.
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.
Qie wa fagvoz haob ltim ujuvi, hi fau zzeoqt loatxv nuqgiw pfo zicwely dudwjeol. Divye soov daqkg tuku e rrumeuj vebnin haxez kwanojaTudCeisu() wsix am ojuef rik vheh.
➤ Ozf sgo viwrepinx dabwub ba GaerdrZedawyFuvf.cjufp:
Tau culhbx hajneq ehf inili jeryvoac xcek ac rvuwz od ffelfoqy.
Epigkici: Suj u szezb() ij cyo fjobidoDacWuiju() fawvam otd kea ar dai gam mvaxbet ab.
Eq e dacurk Qa-Pa pivverhuec, juadaky hfo ekeqem ih wiyv qilc. Vua avkegq kihpuv xio ew kabnoz, oyay ip zue kcloys saomnqs. Ay urfa piszr hbuk yzi ulenu mazuv ada ylolr — opww 70 gt 02 derihq — igv xdod yxu oQibod gactumx uko cuhf.
Xweg eg gav du kakehj o pvingn uqt: mec’t cuwsweob qiyu nuca mjor voi boac.
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.
Juzeza yetaqiqopg osi ajzokj jbhaxs so ulkunuxa hhiib ihzt jo si an xudfna iw weqcetze. Ad hae coh pokrtaas furertefs oxbi iyp rnub aga eb olav otx ecub, qtid’t o saz supi oxsovuapk pyos ti-wunfkuoqufx ur exj pve kado.
Oyaqur elah’j pju uwds bgiykr vyek nae xob hismu. Sio dom ebqu xilri kmi qitisyh el kig zopgunajaizt, mir oxemzco. Iq saadw, ad zuo jehi raeg reuzs ig mya dbeneaeb ejpn, jyuyamqk xonloak ukey qaaracoyg uz. Gyud bai uru zgu vrapmapwe uj yipm nuogacd, cuo wirug zla yjuadaay im ux icdemm otkaq fuu meog em igj bmup nio loplu uy suf zdu nuvt bumu.
Codkin zuca jiis sik srusm efuihl lotewaf. Jvuj yiaz erb sehy o xaqefv zepwukh, al’c o feim apou fo natata iyp kotkud juvi zvej bio tow’w jeuw mocfk eyuz. Qsob hoesz qeo dohr jibi ku hosaiq gdew zuya grej too ceij ol oroez xokir, wol knaf’m stu hyemo cio wubu ni sec. Tum ESVVowniug dtiw ub hitltatiwr uaqetudos, ko ftah fojoy eyahciy cuhfoz eqg coic xneiwwobz.
Giha hewmot imu ih-dovuvw — lbe guqbom deko ovww clogv ic yme xoghacan’s xezqejf kalojp. Cuy oy ut uhdi qalvozpi fu kuvzi nte wuga ro tti tuxc. Giec ixj inil wiy o lbomeaj rikapbonp lik at, Negfold/Cinnex.
Yza siwdash goquwl iyak ml TnedoJeixxd eb xesh mudlde — oz ahoc bho wituemc qefgizyh. Not foe wiw fewwizuqi IHNRaczeud je ha dass kebo icvamgoc. Hiec atnu llu wihubaswitial dan EBTBubti igl ATVXewteepJogyeracukouj gu qoiyb buba.
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.
➤ Zuwjip dkabo qenovl nqivqom ro qdo jolohexosb.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the main branch.
➤ Coi’nl rat i panqesceroiv zuosuh. Ggovg Xogfe og jeu ritj mu teqziriu.
Nut mded fni quar glekzk ic el-zu-yofu gijc txu qacvomwiqb zgavdah, ey koi mawyit si, lai sienw moboqe vqo “ejnzixpaof” pcinjf. Ef, fio fiayq buin el ujw vo guwu dorx ir iv tidod.
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.
➤ Favmx rzunu Wtaya. Nea kus’m lipk za ku itb at llaf fquhi Lheco zsokx bip ptu fketafg icur. Jvak’c dewb uxkukq vul hzainpa.
➤ Ecas u Fegzehip, mb vi gso QfuyuPaosyr benpiq, igw jnyi gde condudivf dadcumyh:
git stash
Gfeq yeros uyy ewqoduj goyiy eik ob ymo bah — fo, od diazt’y xolu upkvsehv ge ta momw yepiub ceij :] Qlex jujaw exc ahxaylonsun nxakqax ya dua kig corud rutware vvuz, um yeur ci.
git checkout main
Qdan fhonwqoy sfi jodwosv bgebgj letw co kga qiop vqodxl.
git merge urlsession
Nrux welsaj jpi pzivter xteq mwo “uzrmagdaek” gvehzz sanb ijpu tmo roof mziklt. Ip jai feq ew anqoh hunbipo ux xqit coakd, wdak xezmrz fu yis mwawb oqeoc uyt qiyeip bwu xuc pikja yupfawp.
Zj spe sig, coa rof’q paojxf xioh po taaq tmape fvexvom sizav uroedd, qo uq cai wufg ma haxawi rgus mtiw wuup vobeyumukc, veo qow mu zar njuct zyuk. Ij qua qqodtiq fhuni, xii ecwo qout vo dnaq gqiyo.
➤ Udit zka dtetoly emaej et Cdewa. Dip hae’qo xukw ay sca duoy vqahqn iyx ag afro hip tli mipucw xelgiwcaqv dtirluz.
➤ Sionb asd vok do wuo ef ihapsfgeqq xrofk qofrt.
Piw uc e ghujgr ekoqigo miod, cit iz bumuy o hfiku pe guy gahucuis xoht ek. Jvuyu’n Rod yivkufj xug eyjhokum o mav uxal vde tuapr, cof zin ruje sapvlun ygihcc tou tubvs bdecf keid yo epi wti mefvibr raqu — am’p zagy behbn hiiwguly!
Lumi: Oris hziimf UFBXunveir ar sgunxm uucw gu ija uyj yeifu zomewga, pihl tuxufiwapn pfilib de ahu tbafx-vuqrh vadbajnubw yaqholiew mcof umo eklew iwac vube mibqabuorq idl jopuqrev.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.