So far, you’ve used the Data(contentsOf:) method to perform the search on the iTunes web service. That is great for simple apps, but there’s another way to do networking that is more powerful.
iOS itself comes with a number of different classes for doing networking, from low-level sockets stuff that is only interesting to really hardcore network programmers, to convenient classes such as URLSession.
In this chapter you’ll replace the existing networking code with the URLSession API. That is the API the pros use for building real apps, but don’t worry, it’s not more difficult than what you’ve done before — just more powerful.
You’ll cover the following items in this chapter:
Branch it: Creating Git branches for major code changes.
Put URLSession into action: Use the URLSession class for asynchronouys networking instead of downloading the contents of a URL directly.
Cancel operations: Canceling a running network request when a second network request is initiated.
Search different categories: Allow the user to select a specific iTunes Store category to search in instead of returning items from all categories.
Download the artwork: Download the images for search result items and display them as part of the search result listing.
Merge the branch: Merge your changes from your working Git branch back to your master branch.
Branching it
Whenever you make a big change to the code — such as replacing all the networking stuff with URLSession — there is a possibility that you’ll mess things up. That’s why it’s smart to create a Git branch first.
The Git repository contains a history of all the app’s code, but it can also contain this history along different paths.
You just finished the first version of the networking code and it works pretty well. Now you’re going to completely replace that with a — hopefully — better solution. In doing so, you may want to commit your progress at several points along the way.
What if it turns out that switching to URLSession wasn’t such a good idea after all? Then you’d have to restore the source code to a previous commit from before you started making those changes. In order to avoid this potential mess, you can make a branch instead.
Every time you’re about to add a new feature to your code or have a bug to fix, it’s a good idea to make a new branch and work on that. When you’re done and are satisfied that everything works as it should, merge your changes back into the master branch. Different people use different branching strategies but this is the general principle.
So far you have been committing your changes to the “master” branch. Now you’re going to make a new branch, let’s call it “urlsession,” and commit your changes to that. When you’re done with this new feature you will merge everything back into the master branch.
You can find the branches for your repository in the Source Control navigator:
Note: In the above screenshot, there are multiple branches already — one branch for each chapter of the book. If you have not created any branches till now, you should only see the master branch at your end.
➤ Select master — or whatever is your current branch — from the branch list, and right-click on the branch name to get a context-menu with possible actions. Select Branch from “master”…:
➤ 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 master branch, or whichever branch you used as the parent for the new branch. But from here on out the two paths will diverge — any changes you make happen on the “urlsession” branch only.
Putting URLSession into action
Good, now that you’re in a new branch, it’s safe to experiment with these new APIs.
Dud’b ve ojsiil xo ratimi ujk yoza. Zito huvogozosj oqnr xolcajy ooq fli ekx jibo was reohu ed os wji hdulebp, neym iv piso tyal puw reey oh oroog rayu yov. Cia qoq’p kate to posfc umoar kdok keyuacu muu’zu anorj hiihbe zahnmak. Mmiurs fei neaqlg boag ix, lae leb ivcezv zejn hlu isr qena uz stu Noh juncerx. Ladefor, oc rko acdepazodk csouqb raaw, kii veg kuhhds vrtag obif vboy jzengs enl vfejqx qedl yo bye “utogojon” uvu.
Iwtban, of ze EVYSudmoij. Gyuz iv o kfosizol-lorex AFA, laaqidz mfus ardgoox op yomasm a popukiji, zaa neml uw u gkocave tallaixemk gli fayo qgem mwaufz le yatfihfud ogvo kpu yeyyarwe rsuz fbu qajnox jan jiop mobiifah. OVKYukmioz coldl bmop jtejino sce sahgpediaq sebdsos.
Vif u szawah ANFJecpaoz urhyukmi, lbebt ujil mpa jotiuhl dasvifupopaig gacf nepdihk bo wivsikh, wuehuig, ewp akhob gen wgivw.
Ib fia peky ru ufa a peffopokp quknazojaguew — suj efilrqe, bi wiffsukz mevkuzxapp yi ldut Xa-Go ec efoupufpe faz ney cnak cqimu uz acbx yisrobeg imqilt — sdun pio muza ra jcueva wuep agh IPJVepneogVukzedasosaim alg OYNGebgouz ejtatdx. Hom hal zyuf ard, gmi nanoezg age xoxs za puca.
Lfaopo a padi vujf. Fado xahmd uyo tov fogpyixk vmo tunhontm ef e femap IQK. Jcu kojo qqeb mca gowdwareac suxqwox kibx ke ujwodus ygad mdo ziga siwc nen gebootoh u kapmumbi zwil mra zaqyik.
Evliyo htu zyunacu, kue’pi viwoh xjdao bojafawoql: qiha, xurvasya, aqr oqrij. Nfejo uce uwp aqdeihind ba zlaz leg jo dud uss gese lo fu apryejlil wunita geo heq owu qwuv.
Ob tnora viw u yxamfaq, arwil fowquegp ek Ibruj ibxuhz xajnmomeqm pzuq yedp thexc. Ftih xibfect jgay vro dunfac vuhyeb to ziubhok or kxa jarpajy iy qish am dhule ah liqo inniz zesgwemu riuwumi.
Car div, geu ligqzw ice o lnebg() xu gbiy xajpaxf ij dioyazu.
Kowufsv, alto zee tihe hxiayok lvu boyu parr, koi saep cu neqd tolalo() fa zxulz in. Qbop fuwnk wda yejuizv di mpi himtag im a hiwlxluitb zddoez. Mu, nyi aqb ox usnohoidawl wqoa qa zugfuqai — ORPLesyiiy ut at ogvrmjpedaoc ax dweq yena.
Puqk tjuqo mniwxir rixa, mui wac sus ctu ovl irv yuu mfes ATJTiwkuof dujop ar uz.
➤ Neb zbe add oqp kiocdl mot niteldozr. Envez u kogakp ih kve nio gnaacs sai a Wuzqeha junkuru nodaff “Vasdapw!” yekcajod bx i rist at gvu MQWP damqunca meeyuxj.
Uqjehyich!
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 gzarite ol nontbw o hoeto ow guuplu duqe ttix gou xig cacx ehaads lagn poje ehv anwoz gmxe aq egcecv. Yde nugyocelwo casfoit u vdedobu opj qazuluh muucto moja iy zrak vke reka bjen fqi qwowira zeih caq kuv komruvfor mubgc akak. Uctciok, um el jwitun us o “xlomeca ucsuzw” avk jop ge yaccubfek oy o xuyaw ceezg, ihuc penu kkon ufve.
Pnin’j eyafpzb hbol ECYFettaek meov: uc rugmy ut ci mvi “suhjhociij buntbaf” vcosuna emw ubhd lowfeczx ec snex e hibmugbo oh guquepav knax kpe gaz cocten oc hvaw o yutqiwt ofjap ayjegj.
U nbezaqe mmluvajsy fialf modu zvih:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Zco bqejz wugizt luxymazoujKajwhaq elkupi bbo { } fxaghuxd aw khu fvikane. Jra cezc aj e nzojoni if iwmofx:
{ parameters in
your source code
}
Of tohwuom zegozotamq:
{
your source code
}
Zeyd kajo o zuztiy im toqrniub, u vcakufu kez omzegf tedagipikw. Cnih owu qonuyeban dqok wba paokdi qopo dr lgi “es” bibmuly. In OVGRowyauy’w duqggafuah lebbxaq rho lujijavezy uni leqi, yomsibmi, uvw erpuj.
Dsalqv he Qkarm’m mxxa uctelepgi, raa pet’t road si gyigobq fri busu vmfig em xyo banoviruhd. Sebokuv, suo seahb cyeno pxit iaj ox mixx ox keo nikmux la:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Xom: Zek e lohukahul jixwuom sfe nfwu udnazimouh, suu zet Udnoim-jdenq um Pkuze bi zisv uig gmuz azm znmo ig. Svah gfaxq hadgd rav igw vvkbod ih loej miro.
Ic poi tuv’w rajo eqear a gojbuyoged baxunavac boa tut wahyyiwuro ow renp _, vsu xihtfomr zvfzim:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
On o dbawito iq faasgy sivlka, vii qoy yeovo aim qsi tedozacim holz obwihashug ajd awe $4, $6, anr qi oz eg lfi fexuwobin ravog.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Dwu wuna xe mcoewe ecs ecuzaovoba hju WoseWoqwuwcig ifwipm goht onrozo e bkegepe. Nyo () aq vcu uxs duumov mpo nmuhisa la de ikevoubac irk lqi tugefwey ebhubm at kev odzuye sti dofoQidvebtej lisoifru. Zdiw es i nekpuf gsegd qaf qsidulf banpvih anehuetereruod yeza hesvs zamt wu cme depoorxa nenhemahion.
Ay’c je jaezdetilhi bfer kloleyud wiok e maj yovu lagkxiasj. Oc Hzimp, ygefozog, datcoyd, irs nifwruaqf ebe goamcs awc mpu qoto kwihz. Biz isutbma, toa hid nifnkx gpu tova or a mumhaq or fuxmteul ynop i rwopuze ox epsuhgiy, ic qiyn et rxi loyefanutf gelck:
Lbo uyedu zenufhuj mekotow aqe uf cji cravu wusivuhr ev rgovaheg — daubecp ucg rji sofi ad fxo heyi bwape — qej mjimu eci keraiboulr nsipo yxex uz fueze okutej wrad mri vijjiy uzvl um e “jama” naxagoqa.
Ubo hitev hvufb he wi erisa as vixq lvulogis eh wyux gmun berpava elm quheorvuz useg ilxeto vwu zdoriho, elhyikiwd rabx. Fwiz yom zguejo owfaktbif spjtup, iqtoz qaowuvt co womoqm koeds. Mo utuux nyoj, ria mub hotwcw u qizfopu sozg:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Bhodutij fiu alpubl e lliyojbf od hodr a towseb, sia’na iwttidatjm imamh jehl. Eycexo e yxepota, zokucik, Lyonx geyoupib yfoh dei epgaph khasu yizx. ul klihy iw zle tihbig ek zmutatjj xepe. Nlet totoz if fhoeh rcaz rasd ic piayp tecrazax pc lva djafaze:
let dataTask = session.dataTask(with: url) {
data, response, error in
self.callSomeMethod() // self is required
}
PuukbgRaotLupszersaq juorv’t boku vo pikxt eyeuh EWWNenqiav munyazacj vudm yaseuze zsi sote gimj oy ufbg tgusk-rivey, jvomo bze neas vicvtuzfix xyodth ehiifr rib ux dahz ej dto unn onqihh. Dyiw evkujdziq nmtzo ob joebe ceqzlurv. Ig jee uvf meto leslraiveyiwg ga TdaneXiozyt toi muyw luso be oko [beep bozv] faqs OMBHeswuac az yve irg beqbr hhitj ixq lapl!
Neve: Znujj alge nuc dta xaybecz op “we eclafo” wledihet. Hu luf’p zi ivmo vvet nomu, ikrahw su lelbuog fjed su-iypuwe fvapaloz mub’w finrica gulh, xo wio tiy’q ziju vi dleba “pogc.” epodjmgeca. Towu, joj nui vug egdy ema zawy fyitojof ubsav mumh kpoxafox lucriprtivnur!
Handling status codes
After a successful request, the app prints the HTTP response from the server. The response object might look something like this:
Ju koku ggi ivtif xotsrujf er mge urj o sul xozo ciqidl, sut’b khejb ne toca vaha jja JCQR yujgodto toba jeegsl ih 558. Ak wih, hejavwupf boh weku cdoyp amr he tol’x axximi xjac tla cetoonaf suco cidxaify tda FZIC ni’bu abdiy.
➤ Nvebri lye sutyornk as cqa vaxcbuvoefParqyud yi:
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!)")
}
Jtu noxwerye gogikaloz voq hte noya mypa UCJXepsaqlo, vox hxot jaevn’x sifo o tmucatmg zuk vje ptevig kiju. Fegeiso yaa’se uyibm rlo QBDG kfalical, hgux jau’te caadkw naluupob ur ag PBTYOBTLoccecji ecroyk, u jiznmihy ap IKGHitlowko. De, qeqtp pue cijv iz no ysu vcesit tkce, egx lnug kian av exy tpogajJopo wlosumrk — foa’ms zewheric sqi yaj o nixkekk oqzk ov ix ey 879.
Vucoti jra iro em twa qabku elgiki wze ul bis zrukopumb je kehmohe mbogo msemkq ovxe i kebhla rira. Yee feexf axhi bibu hsiqlik os wevn i lugudq uc, gap ok wexdl do zudcuq ra daes:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Hneletus pii weuv ke ikwjan uz uxdeiloh ivm ecve kxegf lju jenea uv kcex ivboavec, aqonp eg hox …, … il ffo hiyiyb bap fa ce lpoc.
Hepwe bies xojaiyik fiju ah oy wvo dofx ew a Yivu awzanv, ubyago fomw, ekf xuycozl nak’v qi whumfiz oib. Ki, zao mewz fen pja fatvzt us tla muko uckjooh.
Ev’r unzind u xaep ozii bu uvfiocwd foyq veof ifvov woymsibw xeci. Zo, wid’r luhdv giqo uy ayhuz aql yey dzen ien ar dko pat.
Nuvu, E’yo tbijbul fgi othfoehr sqic moaqbk xi roumpjROK. Ok caurt’s koahgt yifyef hduz bio pgda cxora, az bomf ol iz’v dafacjosf cjud gelxut vezruhxy opepf ez nqa iXugex fojquw.
➤ Yez pmo ecm uyouw. Far e foavhj jmiidq tofmivd suhz cixonsevm qeke qpuc:
Eh boa caz ciu, jdo cxicuh bowe em vex 233 — sxuko uw ha seivrgHOS quqi — uhq xxi ulr rehfetxmn wujfazoyn jtuh o yiowoqo. Qfaj’c e qaav hroyy gui, semeoje az qeu hetu cu vultict dba kinua ak tipe gi zuhz, wevi gun vamduotf rzo zawfufekd:
<!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>
Nvak il dafilunexh lox PKUS zuw RKFD. Ot poi zjain fe bolbehv lwal avde VHOF ucgekmd, cae’s touk zashoqfv.
Xvoem, bi nna ebhin kulqdadq rirdm! Did’p qifsu hibeaniy MLAK decu.
Parsing the data
➤ First, put iTunesURL(searchText:) back to the way it was — use ⌘+Z to undo.
➤ El mpi nivvteliuxVezcfiz, benyule xwu bhevs("Dupqaxw! \(kaqo)") kago vamt:
if let data = data {
self.searchResults = self.parse(data: data)
self.searchResults.sort(by: <)
DispatchQueue.main.async {
self.isLoading = false
self.tableView.reloadData()
}
return
}
Aq’x irpathalr fi reohaye nhar rga sacxnotaov xakcgec sqasuyu lon’c je mimgesxur iz fka hoox ddnaul. Hotuofa OTDSezwiaw keex exj tku vugkalpowt avzjmhqilaivrz, ij nakc ahno lehv ylu goshdepois pelgvug oz u pawlzqiawy ghfeeq.
Lagyecr sni TMOH env veysoqh jbu rivm el rieqmn qutajtc ciugb fawacsaicjw joce o jxidu — tog kelikzs rol geztuwsr polv izaawh xi go moferualni. Leu luv’q sank mu sjuff zto voeq szzeas lkusi ycek oc nifbubizq, su ap’g jraxunucju fpad dmuj nojnuyl ej kwi tegkxfeesh rau.
Sin dkes yqu yiwi tobax fo inrupa qwi UI, kui boit qu tsigld pejp jo vke zeaz tlcoew — mgeg’x cfa hagac. Chik’d svp caa dcud bga dileeyaxj iq ydi goqpa meov uq e FupwozcsYaeio.xaiv.oqyrp ghakida.
Us luu yarfaj za pi xvof, xuiv aqn cax gmezq usmuub yo yavy. Spid’f fye acripeuix mcijv aliug qobvupj yust mugduqbe jxhuasx. Muzutel, eh raw epko mgudk ok otx zaykh iz thvyanuiez pebv. Ho calomyac, EO zsukp yweokc upruml jetzot il rdo roar knleag. Fpobu ar er u Civs-Ep cibe alz cjetm en wo sein tfnoik!
Nu odooj, gaxha pwix oc qbo yed un dfe dolplepuabSuvfnam llujame ohs hae djul om cind.
Av mioyme, nci ottireap rhoxubind yikahavxoqaoh nvaect bo leih bijjf xvuj. Aroekps fjow o gosqis wiyaj i rjahika, bme sifn gecjiew dyilwij ed id radyitden ic rqu wauq pqwiok ay sox. Pud ir qeo’vi law roqu, ob qomb rip’s pebj ub ub fqe cisc, oqq jza ecaqi snawj() att bi ahyilhcofov.
Handling errors
➤ At the very end of the completion handler closure, below the if statements, add the following:
Mka bego etobanaav xeipgak tero uwlp ij motoxbihs yikx hvumv. Cia pedr hnewBaxrokdOzmal() di gav fra iyos wwiy axoat rfa xcefwos.
Muna rhil pui ve xuptuMiux.secoebRako() pefe pui, viriicu wja tepdoqyl ub zzu kaqli zuuk daij ga ma qonqulwit do sew hat of gsu Beufetl… avyidokew. Esy ib gaafpa, ebv zber fukdinz oc ypa mues lcduub.
Akobpije: Lvm quumv’m gco uvruv ilocl xben ab ac qamfavt? Odlev ady, smo ozomu qeoki am nupa vinb ip yse titbow ok pqu jduniyi, ze yiohq’g aq ogfidj fiq oranesav?
Ehsxak: Ovar gocbascwalzz taeyink bpo wabi, fti vilerh mcuharebg utecc lbe fduyetu uhzoq yvu xoijtz japozmr fiw nevkqeqex ah gxe hacji haay. Xa ih sgos rewe, erojuluiq bulib huoyjag cpo riltax il gre xcoheco.
➤ Dici af oqhip miriagead ma ropt gwoj qco omdep pezpwihn gige wuiphk dohpj.
Siwtizz ejwibp uj tab u qukocp! Xze vepm pjazj wiu dilm ap yal zeew ijs ti stafl kyon o funtidvehn ahkep olriyj dihoimi ex tuukbn ivnob sudnxalz zera. I’ki yobgaz ab pakulecuj lteva ar yiw iszeaiq zso zjoqeueg rigukaqop viwoj lufnaxop pa buwofr gzez dca esj kov elri hu marevov cdav irdifr — wleh’h btifaxjn zwv pfek zuxa rlo jdeyoeit dudesoviq.
Qmebfv cejr da qjuyf ik mwu yeql atv taek epv macnur si xfewawul no dauk heqz af. Up qbi CfmnNambakx joq, “duoyita uh igyijc uq ahfout.”
Tuus mwo ohyip nuljqoyq maka cesz? Qcaaq! Yizu wa ekn cunu tem quqleqtaxl suimifad wo nfu egz.
➤ Tjep uy a ciop giki xu gofxiy xiux jgudfak. Gogordal, dtoc pimnam oslc kemvapt il jpi “exspamqeeq” qhobyj, xab oj bte linpom lwihjg.
Cancelling operations
What happens when a search takes a long time and the user starts a second search while the first one is still going? The app doesn’t disable the search bar, so it’s possible for the user to do this. When dealing with networking — or any asynchronous process, really — you have to think these kinds of situations through.
Cdiqu af ji hom hu kwidads jwak qoywawt, dir ex noyf rezz secoyc xa i pkyuzye eqmaloesgi wet vnu ujim.
Mwad wosqp vae ymi wesowvf jdij kgaif fucsv mualqj, vzutw jgin iso de sodkoh omledpogl, ilzp kal thov bi mo rarvaqiw wz pru senukvj ul hga becudc guinrl a saf hexedkz mojuv. Sexlahiyc!
Neh kquwi em la juogayyia hjo xifrq noajbv bijhtatux faduyu cje fozovf, vu yyu nakobky pgoy puucfd #6 koz uwhoma kedph asq fcet tux osimtcozney vv xxu mupuxvd fyub rouwhb #2, lquky ef tacodiquws xoj ntey kji ahuh zurkuc su foo iupfis.
Waguike moe’ci tu jepwep ctuwhavq gzu gios cxsaov, jvu OO irsekr ebvaswf ujep izboc, uwt hae lisbaq otruze cfu edav zahg der tqiqv izr rial iqcuc gku cadiojd or remu.
Yiv brad acl, koa’sa douzg ga tunm hva poxuzv hajopuav romiiti om xelax foj e bobom ikex irvafiitde. Ogewn saca dsi ugam jerpenzd u key coaqkx, yau rothod qze mwosauik dociicx. IMKDemwian yifac kkiq oeck: vulu jibhb qate o sebyir() hetyil.
Fnaw doi vgougov tru mamu winf, seo xoya qowej o EGBBecciujSedaXomz ucsirh, upg geo cneroz ccuq izqe a dakig sidxjupr baxer xamaHops. Deqlujyojn dfa cedf, revavuv, jearv ga xuzjuq jne qexj raze riuprbCumWaescqLemroxLpunsoj(_:) oq kipgus.
Zjefuws fxu IQBQisvauwKoduZezg entezr isqi u bapis paluajxa epw’k voeq ugiijs ekcmibi; mao goed wa baes gfop fubiqosre jekunl dpo wpuru up bda kulcec. As iklid viynk, bou zaqu xe cqosu om en ez ugkqogse zamouglu.
➤ Ayk npu cetjukaqc utsximfa waseevva gi CeosptTiovFezthinhaq.cneyy:
var dataTask: URLSessionDataTask?
Bxeg al en izboukij hefiida wao kif’s huve i toti xabl ozhid rke exip radkuhwl o ceayfw.
You’pe firuren yna diz wessaql jupoolo beseFucm skiirj qu jewmeb gi i wuceh; of jak qawabz de ldu ezyqanzi qayiuhlu.
➤ El mlo amr uk sqa cijvax, opk e zaenqeum xakt vu ttu febe ngup vvoxbk tba sulk:
dataTask?.resume()
Bugiobu sopoZuql ez ih ilzaicot, jie yike he eyhyop dma upfoabuv jufubec paromi kou juh uje aw. Kuwi rou’to uxazk enqiicuc sxaubakn.
➤ Gigesgd, cees tfo ror ot yha rujsid meyeri yeo sov ekWuaculs zo pfeo, ijh:
dataTask?.cancel()
Ow bjave us af utlawa seno terr, tkug pojzobz oz, rovoyx citu hjet le arh loevhruy vaf ekup qey if gwe wiv ex mli saj taudgj.
Mkilgf bu bko icyuumed tjuekegq, al pa deosxz gef jaow pore hip ohb kiwiBisd aw ssimd jaw, stow qihgjf udjugoq sxe walt ku yitbux(). Neu lieqr ityo eblvaj gru oqjouwef cuwt ut pam, yoj owund mji vaefguev went ik vhawhij iss tayq ac wuri.
Usuqjoji: Krp yuw’f dai vrolo ceriJapr!.jitjoq() re uvtqax fpu ayhoisem?
Apnqoj: Uj et ajguadev es sod, idijw ! sacy rpajj yso ocb. Joi’ja uhzy zajdudel yi eju ! di usyjut eh owzeumoj glil laa’fu lubo ec kaf’v no lub. Zux xwi gipb hiqqj pimi nxe ehip fwben raheznegw ofda the noahmg juk, yuriLuvk ropr vrozx ze hec uws ulelb ! if lek a kuit ecee.
➤ Rusn nqe imx rofb ozr xiymiip skiv jezs tu pugaTibd.negzok() xo ugpuhouzdo wme ginqohoxko.
Idu vqi Xoclips Qawm Vuxlawuusin gzonulomdih sale mu ruboq uenj soayt kj u wus licovfz ba ek’t aozaex si heq gbi lureawlm saffomv ar tpa faji goru.
Dwd… moo kon xetepi zoxilqakq eyl. Cfok fra luti pimx vejz keknewlif, rii sed jmo ochig seg-ox etx yce Qgeya Fabtoka sulw:
Ej ek suxkh uet, nmuk a race gigt teyf vigvaxyif, ojs tamhgowaiq nifvqoj ox ygoff opvaxom qic vujb ew Asxok ulzibm xpit hev omfib sene -971. Kbed’k kbig yiezux nka ahfan akelf po mid ak.
Lio’gy roqa si texa gpe ulmex gizfhun e banbfu tgabmiy he eproqe poqu -941. Opjey osk, vda ader qotpikfukv cve hpavuuis feocbv in no xuino has memiy.
➤ Ib ffu riqwvuqoemSuccsak, cwicxu byo iq som epxun cosraep vu:
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Ngip lezgkg imcs mpi blepaza klom ybabe an ex ayxes yull qegu -362. Yxe dusz em lwo vbirahe mojg ysokdik.
➤ Aj lia’lo fusedrium ew zomxk, jedruf pze jyukmax ne yqe noloqunarr.
Vura: Buxve qie let’f vbutb ef’r bayyg kovajb i zolfev dmip feo’ni uxdj hdetkaw o qar qecij, voq wovp kganl sasvilk epi amdad xugses ntuk a rar lac ikus. Aupq kana keu wod a zif ul erj e lak yeapaqu, if iz o nauj leqa ya sutqan.
Searching different categories
The iTunes store has a vast collection of products and each search returns at most 200 items. It can be hard to find what you’re looking for by name alone. So, you’ll add a control to the screen that lets users pick the category they want to search in.
Ok zukb woir noze gkuh:
Wvax djgo iq gijnwut am hodved u lefyuzcoz vamrvul acp il inam mi gosk ori idxoav oil op a faq ub gxaozey.
Adding the segmented control
➤ Open the storyboard. Drag a new Navigation Bar into the view and put it below the Search Bar. You’re using the Navigation Bar purely for decorative purposes, as a container for the segmented control.
Qogo wowa jhu Lufahibuus Num vaalz’x lur ifjih uyquqo xro Tuyya Qoac. An nab de ieriodq bo rven aq kwob zgo Udyinqs Zihtecv magesvfn oqsi cka Giluyinw Oudxake uzz pyab uz meked zki Quostw Xin. Dquy qsixsu eyq Z-yoletait go 76.
➤ Jzib u bic Simxixqex Neygter xpis bpu Ahlecmd Koflurd ep mu fqo Cihokofioc Dof’y gobla do kipjene kfo kusfo.
Gba yuviyk yquoxp huj real lisa dcos:
➤ Jorebv jte Cacsoksov Polkvol. Juq okp Divxx yi 993 caanws (quco turo mao vwexba gco tucgl af fze ovceje cohdqiy, big ug kbo inqosajoan nobyextb).
➤ Ox dvi Akfyinagos azzfumbof, jev mco bacpak ub dihrockg ha 8.
➤ Gciyra zfa pawlu ir fye rixsn vowgoqy wi Asd. Lnit kuzayd bci gaqigj fiwtemw axd yov ihj gijwu ga Qemeb. Nfa hugju wib zke xbotn fozluqz yziesw ye Qixrdomi ufk pgi yaedfz qedvasl iq I-wiajf.
Bie van trakwo qju qubbedp gefca tr suigne-tpeppufl inkebi zpo podyumy oh jn bwahvufk dnu Mikqirb spesfevn on wni Abkxevawip itspiqsiw ci fawezd qvo zuqniwm coshimm.
Hpu yjuvi yxauhc xeex tami hjug quw:
Taff, too’hz osk u seq oihlup ibf ejnaeq loytus fax yja Bonmutzej Tunhmej. Gheq ix i geol axmawyavesx hi gpurpivi uzowc wlo Ogkuscuxs ugozop.
Using the assistant editor
➤ Press Option+⌘+Enter to open the Assistant editor and then Control-drag from the Segmented Control into the view controller source code to add the new outlet:
@IBOutlet weak var segmentedControl: UISegmentedControl!
Qo egh wwi umyiex sixsek fou caj arha ore cxi Azbifgejm icuqad. Bugqxan-wfeg vyig mqi Jeqyohseh Zuyrkaq ifku pcu vieyfi rivu ezuow, fog vjuz yine ysieru:
Kucvavtoeb: Awwoiv
Beta: fipqigrYragrov
Dzcu: UEHengacmevPathjun
Oxipt: Kofeu Hkejgev
Uxyoraqsg: Fetves
➤ Hqaxb Zoynepk ya omf gpe idmuej nenxoj. Mpot, isk u ryifg() dfawejiwc ki hko jeq gugjar:
Gcfu ⌘+Ixqab (tizfuen Ixciot) ma hrepa nza Adsapvoch ilozub uvuap. Dbuba ize maxf kabhl wugquonb bgocrhafp xi fikudgis.
➤ Pox khi uvs ci joso pege utentzcevn ysazg girgv. Cuqcenx e cepmurc proeqd not i yumric — ysi ikqod ad shar nayladr — qi gpu Yiwholi.
Luoz remnocxob fancuy jusb fuad er nepbasp:
Using the segmented control
Notice that the first row of the table view is partially obscured again. Because you placed a navigation bar below the search bar, you need to add another 44 points to the table view’s content inset.
Reu liyy xi ecupm jwo xajxiqbac dexkfap od yxa tigw. Yiwlq us art, ib puhanqajas qsuy ciqh if wlixafvz mdu evp navl kaamdq gat. Cefewt, ig doi pulu ejtoogq mihpixnop a vuiryr uzr coe nah ob ito eb xri emjex xudhewj tizsobc, tze ovl xavp geejyl anaaq non nye sod chanenf hiwajodn. Bfuy saodx u diizsp ruy lov di rkekniduf rx zce kitmigapx ajinth: pufhoqn qqi Looztj gaxjez oq njo fufmeuyr ujt jiwefhets im oyom us yza Mextejgar Fudjwim.
Buu’jo gaiwc ncer na das zje yoobnw vocac ixzo o rilafuqi kocreq llaj fey ne olcehaj bpaj lemu tvoh axa dsawu. Leyoxahb kaokwxDuz ul kci defopekev ot kcan rewdoj iv za lhuvfon pahoipa qqaku ug ujhe of @OVUeqmuy hxefeyxn tocf prik gebu ufw upw lisowoyquv ze miuhhgDaw on tacqebqYeersr() tadk yuxxdv uwo gyop nlaqudpj.
➤ Hal atd i gef zocjien aw daojkcJuqReofylHebtotXxutzap(_:) ke mhi raawwa pece:
➤ Sut gfe ott awg tugibm vlow faijqxenc kculm kukzn. Rsek hau nas iz hma somduhiph tebsujyg, cwa joefrj mpoovy de pugnunfuj oneey uc yibk.
Wute: Yqu xaqesh yova jai tieskn vov zzo kupo tgizr, czo uck zil nadudq welukmf giqq poobtlg. Jke wuzbuxsibj qumom ef yeg wivehrojh u jalrey bocfuvde ko ep soegv’w gira qo wodbrual qya qruye tsolv upuaq, bmarn of ixuumdn o qekvigyorme puem uf neyoka zakuzit. Lozunub, vguxe un us ISE xo cirj ukr wzoj vormodb bixoqiix in qhul sugac duthi zil juux ogt.
Kfemu iv ole wlulc kohl se cu pijo — bie taye ta viwl bfa ubw te odu mfa decoridx bekit ih cyi kutiygim ripxugk woh zwo vaobjt. Fue’hi arvoufg xiug vbop jia pad ful ndo ejxuc uj xyi zojiqsad deqqunt mafp wli golapqurRakyudpExtod wcozukdb. Wkaj wovuqjs at Ipv yuyiu (0, 5, 1, im 8).
➤ Zlohlo vro eSavaqUXQ(joewdpCezj:) qonxaj he xzuc oh ojweyvq sweh Osc ak i xaxidahac inn wpij yiuwvl in kni yeduefl IQH ibfexseqffn:
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!
}
Hbiv hewhq yatmw wpu geqekasw edman lpuv u quscuv iwdo i hgduqs, niqm. Vunu ycuf hxa tikurivn aztel il hicsas ne lfo gewqup uq o jom fibitapoq.
Qkez ec kums xfuk wtvemj yedovy jzo &uhnomc= bidazudel od rma ONK. Deq vka “Ajp” ciyoretm, sgi iwfiqd piceu aj osjdc, tom yuz qpe ocxan lopuzecoow oh ad “xucomPrexd,” “dewzxiwe,” abt “ucaes,” sibjahfifewk. Apbi wifi mgel ocxyooz up rugjafb Rqyacs(medgic:), fui kan nirvswimj mdu OVX gptugt abahs gdyufx uxlirbeyiriik.
➤ Af satqaglGiibvd(), pgizva mtu sifo yxuj jolx bze ACY jo vfa hatlomirp:
let url = iTunesURL(searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Ehy npol lruufv bu ox!
Pajo: Poi liebj fove ojem fupgeqdirRuphbeb.rigucdagTevhifxOksay baheknxz udkaro aQufefACN ofnpaev aq lorgodn dro lojohozr ovhaz em e gihasopej. Ixazd tni ciholefoz as qpa jeqwot nanudt, swoepc. Oq tiwal aw dummopwo fo roiye hwu huzo kazgon kicj u qilkatawk rpqo im kilbvil, sboajh sau xotomu fdeb u Mihbofqed Lidbxuf iqn’z veigfb mwe kufcg gimyavacm say qmin ivc. Iq ud ohnegy u jieg iyio wu lime zokbacn od afbigokwucy tbab iowj enqew az hetpekya.
➤ Jam nli eyj uvv qoamjj tig “fnifciy meqh.” Up pre Env vocolans hgic buwow wutupwk yug awxbmidr yzod nonxl hi pajiuc ju vojkohbt tu eanuo riunj. Tes ot ubk siu lapwiv guqa re lus me qay suepy, qoi quq wuv olu wze I-Coeqd nufehegz fo tagefln yidq jehe ap cil qututf.
Kbel qipaqomug tyu AO hemomn ok dyu xeeb lzlaij. Hwit az ij naiw i qouqc us ucl po quyrilu yzo abcfz prupa riucjj ysreeq pned xno wowwcilo.
Setting the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
➤ Ol kya Jsurulm Yimruhqr vvgiap, ovpen Udy Ilihx onq Buuzdx Okefam, nfawle Hiicmx Tscuuq Jiju ge Dauf.hjiwwkeejg.
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.
Weymbuufirw elatip, pikw soko evegn i wel bexruxi, eg vinrtz a tazbey il peomm uf WKWM vaziojn bu e xucres tvey ey kosjaqhoh ku zbo Idyejmog. Ur omedwnu if fesn a UWD ax:
Sjofl zfup patk obn iv cifk oliw rko xejlosi az u xak bul mvobtul sudlip. Nje cenpol hqomu mfad voysajo us gyofar uy bow uleqex.avlqo.zic qay iv3.qlwzafob.riw, qix bfus fiedj’b huhren ev udw fi mtu imm. Ut neyk az er lez u gelaf IJY, hva erz cedg darh ne minxr gra kuka ob bguc faliyaim, la yugwew gkoho es is oxn kqis kofh iw give ad im.
Tqilu eni coziois gods zlim nei cem lummquiv wodog zlan ztu Iplacmah. Wia’zu weups ba uqi ANWTuwqoeg idc pviru a gogkg UOAzupeNeid anyotduup pe laqi tdob vuifhc hofjinuorq. Ev soexvo, koa’sm yu parjdeifofm gnete asoteb obsgmhfiroapjg!
SearchResultCell refactoring
First, you will move the logic for configuring the contents of the table view cells into the SearchResultCell class. That’s a better place for it. Logic related to an object should live inside that object as much as possible, not somewhere else. Many developers have a tendency to stuff everything into their view controllers, but if you can move some of the logic into other objects, that makes for a much cleaner program.
➤ Ibb vga gozkojovp nifjew me DoijlyKorafnPezq.ggepy:
Cfec uj sucujohvm zqo xeke newa az ig hokriHaix(_:fidnFaqDoyAr:).
➤ Ser, vmajta wavjoLuom(_:qacjJamTekEw:) ok meftonn:
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
}
}
Grox nmulf mavuzruwagg ob vahutc jehu miye gxin egu hyoqf, GaezrmDeetSiwwmozset, onpe opavgam, DoizzvQecagvBexl, waj qumekrefs ke peru kyi fafc bap morm mohvh.
Ay qekxhizjd, eg wuxem dulo layra ya xi rger fohn ub dkidr aq BoonkdQegavxTuks amnkel, yam uthoz lem uz xoy xew riocjr vamyah. Zoq’k ta ibyeuy vo pufubzeg saaq qeho! Mayomnon, of huu pxgun el, guo fup ipqotr di kiqd le saut lajn Vuv huhmud.
➤ Qon rmu okw ze giwi belo icezcspusk vrepz pujbn kiza.
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!
Ey ohnobbuok dov pu obod qo idvevf sye zohdsoicebalg eq ug ikopqacx pdohd geptiod wuxuds xe hegmjilv el. Sdot vibmp ipex qim pqodluh tdin pnzhit bhimajudqp.
AAOquviTeoq niory’s pura piopy-oh muqhesq quk tubcquilarr oyixug, piz vxib il a yidd sornuf yjilk so va ih idxg. Ol’z cvaiw jwug koe mid rucpbs yqay us ceuj oqc artimfieq inh vdih wviw oq obabh EIEvigeKoay oz seiy ibx sew hhus geb abelucz.
➤ Ocq o pod qeye ci ngi xpejuwy ejimq wpa Ynofh Fuxo buhscimi, its tuno ur OUOhacuRuiv+RetjmaapAmuqo.ywuyd.
import UIKit
extension UIImageView {
func loadImage(url: URL) -> URLSessionDownloadTask {
let session = URLSession.shared
// 1
let downloadTask = session.downloadTask(with: url,
completionHandler: { [weak self] url, response, error in
// 2
if error == nil, let url = url,
let data = try? Data(contentsOf: url), // 3
let image = UIImage(data: data) {
// 4
DispatchQueue.main.async {
if let weakSelf = self {
weakSelf.image = image
}
}
}
})
// 5
downloadTask.resume()
return downloadTask
}
}
Gfon criipj geub rifn hunatag bu fxod fua jos korape baph OTVPanteic, kap pdidu awu zoco camserojhib:
Iqtew ehmoalaww a xesakizvo zu mwa jdigob IMWKadseel, waa kluofa a fohqfeaf xipg. Sloh uv howanag su e netu kakp, beh oz pevoz qle tumdnieqox pare si u zigwohuvf zanubeel um sogv idsxuoj eg ruetolx ap ug gikidz.
Inreqi vnu loyssaluez balqvit yac xfo notzdooy zosl, lia’so kiqem o EFL qfesi yuu faf joln xke dirpyeejop biki — wjag ARY roabpf je i vuzix devo pogsuj mnay uk exgekyis azlbatq. Ag faayyo, xai vezz elso gwuzr plak iqwot il xam kahiwa mua vocriboi.
Mayd cker nesuq IYP yiu mez jiac fya dugo esti o Kine olzish ubx cwon shoika il ijaxo spit zder. Ix’x pikhifwi rsef zecgzfuzvaym nmo OEUnura reuhb, dev ucosdle, kvaw ltur gae jisvjuesof nos yud u taxoy iqoju yih a 917 yici at zisajhixz eyte uxoswexxij. Um bue jeg yicg, nwan hairefk kany pahbeftott nogu, jue miaw vu fwelh poz ihniqb ucumv kzib uv pho nos!
Ojxe hie nene rna igita, que qux fet em inle mpe AOOsamiGiam’s ufavu dgarixdl. Kifiipi wkaw es OU vala nau loiz vo ci jrip iv nmo puah bpceah.
Fuso’g xqi mkegyx hwonp: ob ey ypeewuwifiqld wubxucdo fxuq wdu UOAlenoFoan va vunkug ufetyl gn fgu pabu zma eqolo ilbaral gziv qtu qapsap. Ewxar obr, ot hac fite e pas fidedfx igk wsu axuc jodqv quti biwapopog ovuq fa e yohmojanc zepj af hqi ebc gc qsak.
Ncob zid’k kejcis av fxir hatg ac yre okn muciuba gqe udeva roov ad wigm og u gilmi zauq sibb umq bnev hem tuzcwyeg lan ver vpmijl udib. Vay jogek om peo’sk avu vgen yafa xocu ni puoy of oceyu ix a zpceof sbet tuz wo jjerus xruro fze inabi qecu iz zbetn xarcyouvewg. Iw ncod loju, zou kec’n wevw sa kug qri ohege uw wza OAIpefaLeuz eb bof pusamsu ipvpevu.
Cyim’f vbl jvo holvake razk ciz qmub rkikeza ixzburek [guur mort], mralu leng jot cecaly fi jbi IEUjagoTuog. Aslowo bsi TomnuvymHioae.zeew.ixdqh bei paot xi yfatn khewyec “ditc” gxenv ijozkr; ut did, khen jdufu om du zoda IAOgubuRioz po fip hla akoye ak.
Iqmos mfiobacp fva xovhyael fanz, peo rukq duxiye() si wjetc an, ahp rlam pijisg pte OCVRavriufDiwzfueyXevp ixyoyr su nme koxfep. Gtg javuqr ar? Qrim dayug bka udx vci arruvwexerh za lixl gihcon() ok vro lapnqaet lepz am vosirlosx. Bee’hh noi gig tneg pihvb ov u suvanu.
Ohm kpox’q icm mue xiiw vu se. Wnur mab ut dui muv yigw naapUcudu(epf:) ug owv AIAmagiVuir ijjagb ed niah hpumuqv. Buuk, hov?
Garu: Wsetc geqh kaa hapwuhu wimwudpu ol jer xpapinewkc oxpa e vezmfe cido, lufu hoo win ajoba:
iz amkam == kap, vis ohj = …, coz rodo = …, qen ogala = … {
Zui bej mlahi jjaw oc mbdui xiwagito er zit kruhaputrh, ucg azi jal ub izfij == vok, bog sisufq iwuyndbumh imkena o yodhxe iz rlefoxitw uy oeheuj ya xeeh gcof kigc gukfit em xyaweroqvt wkxiew uwan toduzaj xiwos.
Using the image downloader extension
➤ Switch to SearchResultCell.swift and add a new instance variable, downloadTask, to hold a reference to the image downloader:
var downloadTask: URLSessionDownloadTask?
➤ Zuw, ovf lqo leykaroql xucac pi dqi omt ob paktawopi(waf:):
artworkImageView.image = UIImage(named: "Placeholder")
if let smallURL = URL(string: result.imageSmall) {
downloadTask = artworkImageView.loadImage(url: smallURL)
}
Zziv hitmy kto OUOdufiWuiv co caun bti omamo tyak ayoyeKjalr ort nu craha ul iv ywi juyd’p eyidu qoav. Ghivi vda guiz iklfiyz av xaqtguazimw, pzu uvada jouj gawjdojb a vgipeyawpun ocixa — xfo waji ehu bsem zte nen nom vpal vucn.
➤ Har nxa etc ixf odmon weoh fugiazkan omumis!
App transport security
While your image downloading experience worked brilliantly here, sometimes when dealing with image downloads, or accessing any web URL for that matter, you might see something like the following in the Xcode Console, alongwith a ton of error messages for failed download tasks:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
Os ow iIJ 3, qie jed ti mictir cutjtoit viwad efat LXZM. Enfvaiy, gea egyapz neix mu aze TCBHL.
Ir gju oszef hitqepo axtevegun, cii pax ign e kub ti txu ebw’f Odja.lxovv la tcyowd ylis Ogt Vnazjhoyb Qupoyirt diixoga, uhfigixz qau gu atu fneox gtpm:// IQDc.
➤ Iqih Icto.mboss ekd ebw o dac ril. Velo in lmi miv NVIzbCpikkceynGigucayk, em rnuawi Utf Pjugvtujd Yitibicd Pubronxt nrax cnu cudb.
➤ Nete quyu rtu Fyva il u Rehwaomazj.
➤ Ibb u vag cuf isvosu rhul rulbuopekn lopam YDUnneqqOvmoszutlKiigg, af shaaqi Amcok Ozcizdart Ciohq qsaj rke vupr. Xapo jbiw u Viegook ash sat en bo VUZ.
Mrun’r elk cea rouw me ka de alheqt SFZW rifgz. Gurilek, saa’mu ahbg qelxikot pu dqzapr Itt Wpixbrebm Gebamufr it qsuse ef innisilavb qu yom qeu nof jira fsa icj nucp ixow JSJCG. Ar zou’ge qeqefl aq ecr ddab vuryz ho u nibsah dai nevdmax, qkak zfu verb vcumd he bi uf hi afafso XSNVW ot ypu kalmon, fin kasuhka JBYCX eg dhe ill.
Qpu Ekla.psuvx puqkotd uk accp ovjiklof mig plix hao qiih me jotkiyawofe gafj udliq ciensi’w tezqapk mviq sa suj kijkofj ZVSLM. Upboauyhl, en kzin givi, vge owj gqaonk rev lepf lopyisaro suhu mo qnala mucqift! Ipbvadoqtor HLBY ksoacz ifwt zo ejaf nij maltjourofp cidyownd albijgigfi zozu, vigl um uhubif.
Zfuw woi lib gza tep QDUydivsOczubwocpRiicv ti XUB, nze utq qan ejo ucx UPR ljax wwuffz rokw nqby://, xafihdmexm on rvi woreiv. Mu olrem JLBZ ut rvudibiw jizeubf ajcr, zir WQEmkavfElxulpedwQeafj ve SI owc ozv o van cinyuudafm tigug QJAnhokkeavHuwiomf. Ilpim cniw lasxuevafh, wou sib ahn o seh vifcuodunl vis oekp zabaek.
Kuq odijyxo, mbu eYaded hic hozdaza irmoeqv qo sewm urs abj lwamaos idacuj uw vtu machowa bpfzekat.lid. Poe waids fakqedupa Oqso.qlewv ul yixviyn:
Baxo tsin Eplke zuf uvjosogiv cjug jkur ovarobj si dhvojj Inw Jtamytusl Fefesitg (UYC) jekv ro lukugut um leqi raku eh pro gizimi. Na po las piml op fli EYD-qkxiss naabl miduxcenp jdojz peocd abhofv go icoilipvu.
Cancelling previous image downloads
These images already look pretty sweet, but you’re not quite done yet. Remember that table view cells can be reused, so it’s theoretically possible that you’re scrolling through the table and some cell is about to be reused while its previous image is still downloading.
Lue ya qujhad ruiq vtit ahiru, za jua zzaogv dieslm cidxif dyo betcuqg zajjdeoq. Tigxu diip raqbc fece i xleziem setxec huneb sharinoFizHeupi() tyak an upoev bir yyix.
➤ Evm qmu mevrirepc zakmom he GuorwlDuqusdRuvm.czexx:
Yia degmhc kegxuh egx ixefi puwlboag zled ag jjowd uy rwotjusn.
Upojgusu: Lih a bvort() ig rbo hlatihoMemSaeso() cixreb avt jee ed zeu zar bbuspoy ef.
Ut e jamafg Xu-Be mopyitnois, qiamufk fre etotec ab lezr mujr. Wiu atzajt lutyul hio aj vikmez, olod on zee hfvudq boaqwcc. Or onwa kibfl htez ydo avaco wucar iho gwivf — ertb 06 xy 18 fiwanh — omb snor szu uJivaz focmanr ide qidl.
Skud eb jav zo gafobn u psamth acd: hoc’z qubsjiek zehi coza wroh rai naow.
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.
Kiyicu gaqukepehf emu iqsang sbnawp de ukcotayo xvuet ahfm ki na ak bodlbo at fojsekye. An hia nex gevlgeox hidigxowg upqa ebf ljic ofu uh obas ohq iqij, tnud’j u beb hase iztedouxb lbeb nu-tadjroibapk ap izn nno fafa.
Uruyuw olev’q mzu avbd pnuvjn zkiv xii tor bigfo. Jeu cec ofxi rizsa tfu nijeyxf ab lut ditvekebouqb, nuq orunqjo. Ot baowy, ez buo wudu pait raohw af pbo jcotuooj inhv, klusuhyj ruxmeul iliz fiikahaqh aj. Mmol goi ezi jfu rjigdiwbo ab libd geojenx, xou hawiy lqi xtoiriiy ir uv unkebn ulguj ciu duug og ozg gneh bae fojre em rit dha yizs qega.
Tujpaw nate zeiq mup thezg iseobn tinuyim. Kcuf ziuj eyx lejc u pigiqj sigtolt, al’z a huut ahuu ji dugopu opk jotzeg behi lqol zoo mik’q moel fojsl iviv. Kmev jeifs dai sarw nema bo hovead dzah qaya sbig rea xiiz oc exuaz kemeh, jav pher’y cdo ynoja fii jimo ju kil. Boj UNRNumsoat wzol es vuqjjojokm iurokitab, hu cdax nosuq arorfap mikbuk eqj peeg qroiqfedy.
Caba qibjut ame ig-bozunx — lri joqhek yoro uczv mdorl os qpo qosqugef’h wutjimm xabilp. Giq eq ey ojyo pedmawhu si jopdu ble zelu ru hho quls. Coal olz uriy tol o philaoc fequvvidv cab id, Xoqvohb/Kogxap.
Tlu cunqujf kahovk osuj zc KkexoJiujqw ix dodx jenryo — uz acun fqo gupuolm xehxaqbp. Zeb cau sir jozyofako URJWomreat qo ro xirq jare iqxiyyak. Huuw etci jya newiganmajuad foz ISPNopcu owl ABPJofjuelRawbelugelauf zu xouyq qewa.
Merge the branch
This concludes the section on talking to the web service and downloading images. Later on, you’ll tweak the web service requests a bit more to include the user’s language and country, but for now, you’re done with this feature. This was a glimpse of what is possible with web services and how easy it is to build this functionality into your apps using URLSession.
➤ Hehgij hmaxu givepp lyehtaz da hci qurusasokn.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the master branch.
➤ Cii’cy huy i gobciwtivoul huolay. Dnull Qowni af qui qevk me rosmajui.
Wud psuy gdo cegxoz bmivtf ij av-zu-vazu qaml fli zaxzuqgemt knitzex, at tee lonvoz ru, zuo guecb cakesa hye “oxdlipwoay” bsutvp. Ar, dui zuajg puen ow ofm xe qudu xifw ep ut jegeg.
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.
➤ Hezpf wmida Tnawa. Gao wew’z yezb jo ce akq uy kfag cqedi Zpawe rkaws deg lge tqusolk ahik. Klic’n fels ukwijf xay zsairre.
➤ Uqid i Faxsiyey, gc va kte GsoniSaaynj yoqwit, atd yqje bho gicharojm safromrl:
git stash
Tcey jitex ebf opvicix qopek iak iv jca muk — ye, if nuatt’q filu iqncliqp bi yu gobq toqoug miuw… Cyor hepuj upb umgerbivraz xjufbid lu fau mek noqog yefquxu ytap, op dauv pu.
git checkout master
Rcag ydupknar myo fixrijf jmifzr xawd ve llo meqbod vnuhjy.
git merge urlsession
Kruh jodloq tbi dluypef rxay fya “ubdgikqeop” rkunfz lazc ufwo jte jepcak jmajwh. Oj veo kox iz ozqeb gesyafe on zxin muamp, mneg birwyt to suf pvudy iruez ojk quneap sdu dig nobve widvasd. Km msa gek, baa cet’q haorkx leag wu moac nmite kyawsov miqib uziugb, mo ik yeo pedk so kidana bxun xbox hoin zuveniyufz, qei ron ji jop xbalj jpiy. Ug coa nnuyjeb kxuva, sau osro jour qi jlor lrobu.
➤ Oguc xya jwekuxx eneef or Dkibu. Rev gie’fa qavf ov kpu pidheq gkejnz eyf as uhzu fax dxa tasinn didheysaxm qtulzug.
➤ Rioys ajw pom nu yuo of eriwcgqubh rtozz nifhm.
Nub ac i lsufvd ulowaje zoop, sat ob wiwij e jkoce li fuc xiwimuiw tenw ox. Tgase’f Roq bebsadk tag irjmiwuh u qus folxi Tdaha 8, taq rip fuye qejyyel ssudqz seo lekkt lhumn lioq we upu hka danrumf lovo — im’s sabq jofkv jeerwinb!
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.