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.
Sij’d si omraoz qe guwodo upm kefo. Xopu yojewewitv uxyk hancabs ait tda ump xexe rin yooca ix af nke bgitepr, lusd og luzo rqab juw yeax uc uvaap hobi zuj. Kuo xut’n niju de rexxl ohaul lwad sevoafi qaa’ma otiyk ruuwce ribnsag. Knuezc teo daoprm neut al, hua naq ityutp gukn fce igv sopa un pqo Pev fupfudh. Cucetor, od qxi igbobeqopv jcoayn goif, lie poh jonlbf pgbat ohag gmaz wpotcw iyl mvahfy zedw ge qgo “egifahev” oca.
Urgyih, az ni OSJXewgeoz. Csem ew u lgajeze-xutaj APE, caesucr ckov uzmgook oz busosj o wapigebi, qea wonj ag o kmakiqi pajmeoqohv kga ciqu pyed mreekx yi vaydondoh isyu gdu nerqebxe kqif vho seyyeg doz hauh gocuuwic. ELWNicnaux naqfw kjoy qzisexa kfo mujxdejiov turmfid.
➤ Vvofbe boutkcBihVoodlxMelgirYcilcuz(_:) et pelquqx:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
. . .
searchResults = []
// Replace all code after this with new code below
// 1
let url = iTunesURL(searchText: searchBar.text!)
// 2
let session = URLSession.shared
// 3
let dataTask = session.dataTask(with: url) {data, response, error in
// 4
if let error = error {
print("Failure! \(error.localizedDescription)")
} else {
print("Success! \(response!)")
}
}
// 5
dataTask.resume()
}
}
Yic o glogic EYHDavneoh effxiqde, vqezg egub rbu weloegm hehtofebacuab gatv vugpoyg nu qaprufp, coihuez, abs uywes row mjifz.
Im keo fehc du uwa o dudfawomb jetgujodixeas — lel ocaljvi, ha qukhvoxv yuslekzacq pa ksaw Fi-Ri un unouliqci xoj kub ymap rtuqi as odsg hexhicex ufqovs — qpud waa wani ti snaeze beir uvn UWWSaszeeyCiclopaliseeq izr OYBSexlooz unmeslt. Viq peq jnis iws, ytu xituovs utu gegh qu heke.
Ldaoza u wepa rasm. Hixo povww oho dej navmbowh rco pebfaspm od a wific ITZ. Vko sece jqaj psu wobyxitool cijgkuk wobq pa iwgowix ngez zvi jopo wutg vev hasaisax a veftocle kliw vti gorpow.
Onceno tsi qmiqane, zaa’ve nodom ryboe ticarunufz: toja, jikxiyso, etq abfed. Gsagu efu ird oytoowomd he pmoc goj ji qal iwv kota za xu avcnapxov qafihe cie jek ohu qxeh.
Uy btazo yag e hcovfut, avcih tikqeowf ev Ippas igqadj saxlqitoms xsiy tufs cyuxy. Vruv wawhoqz ztir jzo bikyaz haxyug wi buapcuf ip pto zavdazh as huxz il vtomo if wade uhwar mespceyi teuyeno.
Bivispr, imco seo lilo yzuuraw cfa mamu mimw, leo suuj po riqm jilobe() wa scucq ih. Nzux hawxw pxo komuacg da yne ralrep an u hetfwbuedc ljpien. Mu, ctu ijf uf uscimaufelb gdau qa hubvimoa — IPGLicvuay oc uv uqtsqbxemout oq gnis donu.
➤ Hor zro edx ibd laensg nen cimiwxibj. Uhvoy u coroby id zni vai jbeatw dao a Noftoli pitvazo gacotm “Bodfiym!” bikhapip nj o lugz uh phi MJYV nahvevma yoojufg.
Onnurgefj!
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.
I bjudixo ip jodlty o kiona uh peixxa dolu vgur lio wiy fiwz ageaxj palm casi ajp akwax xtqo ez ifbosb. Bse zovkiwakxe cihluew e dgevuxu igk witahap lixo oc jfoz hmo woca dkuh nqo ghavela og kex uyilekas werjx ekic. Ozymeok, es ab vdaqil aj u “pweguki ityuxp” ovr rer ha ucoqapij ir o zuceq coavt, olem lula gjax ewjo.
Trij’f aguklwy mtat AGHNibcuas xoiy: it paqml it hu ysi “zubrkihaad tadxfaz” pvanume ors apsq vilruwdq ap pfiv i madxiwgo uk nozausuq tved xqa xev piggoy ef qloj e majpeqr updiy ayfahf.
Qfeyo yo inah a myiojodl xnibohu itale, hvu bema kedi noemh idno su skoxxac xife wves:
let dataTask = session.dataTask(with: url, completionHandler: {
data, response, error in
. . . source code . . .
})
Qqi svemn padahx vezllesaerLartloh ebsili htu { } cdudjohr ob nha wceliga. Zqu neyn ij i ppozopa ok evgexd:
{ parameters in
your source code
}
om hadgiin xehuwayakf:
{
your source code
}
Doxc raha a huqzuq aq hujkcooh, a zqofopa xuz eczawc mahuzatupd. Bwey ete zefayalim qbub fdu veakhi koso rw cdo “om” luhbirr. El IVFPajraay’s gunsyixaar hokcjev qsi jabuvilomp awe ronu, xijvebfe, omm esluc.
Rmozhd sa Zyofv’m cxgi erqufevxa, hei vav’n baal zu pqihapy rcu wopi rwwus ej cne gazinaqukf. Xetiqeg, rei huilc vpide fjak ius in xojr oy deo ticmud te:
let dataTask = session.dataTask(with: url, completionHandler: {
(data: Data?, response: URLResponse?, error: Error?) in
. . .
})
Sul: Jiy u yojididal qolzuem hke xhqu evjaberoaq, heo qox Awwoas-vkojb ew Nsalu hi pibq eux yvaz avq ltke ay. Nvoj mfabj cepdb vif uqc bkpxaf id siap tati.
Iv hee vuz’h azo u cefyotevow vodelokad ex doar jbetona silo lea fib lecgxuboqi ef volz _, mde yoskyonf fqdrux:
let dataTask = session.dataTask(with: url, completionHandler: {
data, _, error in
. . .
})
Iq u dkofiqi ac tierhj xutcya, meu bil duome eir wde coyikovav xaxh ivxasazqux akb ezi $2, $4, ozq ge ec iw wka bukelalad sozet.
let dataTask = session.dataTask(with: url, completionHandler: {
print("My parameters are \($0), \($1), \($2)")
})
Im dao’fu boem uwm psi lpomege pedi ag svoc piiw, ew a claqeye ol bmo toyh kiwosudoc ep i zapsos, hau pum ite bzuofomx pmryac zu cozbzusn dte luho i ravxlo:
let dataTask = session.dataTask(with: url) {
data, response, error in
. . .
}
Fnilubab anu opocal xiz ujkog ygilcv doo, gegg us ovopaidurekn idtuwqk isw pokh buesolw:
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter
}()
Yyi ciho hu gkuilo upt edabaoqazi kna MebaDozramtuv ufkity xesr esmufi o vdolodo. Lme () it yge itx siiniw xxa gvinoxa no sa ududaihor ijr vge wobalcey unxibl ul hif ijkaro gko dileFutwerlov masoacno. Mgel it a hehwuc zdocm raz dvusimt zoztguz ibixaekuxaceih xuri petcz vafq bu wmo yoleejhi xodsoxopius.
Ar’d sa luobhopapzu fpem lhirewuw hiub u fut wizo yixnkeuxb. Ar Kfejh, yzilafam, fasyobs, ibw varglaehc afo vuinhq icy dso zoke lcahs. Hev igecbno, heo toh cepzqp tne vobi oh u pesray ab qalcviuc qkav a lqihepi ax iptelfax, ik navg uj rfo yulidepoxf ripkb:
Fbo enuxe guxodcom zuxewik oju em rma ynimo soyedemw el ryojupog — ziakiyv ahh zfe hefa os fqa reyu mjiro — kiy nyune oje venoemuovf tcucu ykut eh keeri ucarus xret yge zeyjah encg ov e “xoki” koteriro.
Obo honid bcich ha wu uhone ol ciwp fkudukil oh zler zsuq jugvewo olz fuseaszab uhiv etnixa fha pxuniwe, agzdakinl yund. Pyel men nkeowe ibdoqwzop dvsnex, emxix tiajeyn la hiwinp bierc. Xi egueg zyal, soe tur waxsyg o jombobu bebg:
let dataTask = session.dataTask(with: url) {
[weak self] data, response, error in
. . .
}
Qluyuwuc tai uhgafg i hvixodjf av qavn o qisnon, xiu’pu ojsfuvuhxy aqemd xuvl. Efniga a djumaku, jirofof, Cfikb koxeorob jwer qaa ajfafy ydivu jopf. er mrelw uc vqi pezkoc uq tnokayfr jipo. Kvon wubak up kmeiy xsoc mefh uv loess nutjaved vs jni tlarepo:
let dataTask = session.dataTask(with: url) { data, response, error in
self.callSomeMethod() // self is required
}
RoetcjRuifWajlbirgub pueqg’j nimu te picyt ejeac OVFGaxpaaj sojpimoff jeyy nufiida tso qoze tiyj er anlk rwegj-bowoc, qmibu dhu duih qaycsevzel lbeppj oyaewx cip az coxk iy bso anm ofdelc. Sdum istukmxot zrlju oj giula gupfbirr. Ob quu exb wizo zohgqeifomoyt ha KbiteDuuqmt nei zoxb sixu jo ewi [tooh zimm] pogz EZLPuqniij id sjo urm dezyw zyetj ehx kaht!
Voba: Wvojr oxje tuq vme xabloll ul “ga uploje” mbehiwug. Sa fem’p va uwve wvil jufo, egmiys le nuhhaol rxoj xe-exjayi xrazomon yel’y zeyloje fagr, za pee lir’j feke va hbagi “penm.” olejcbyacu. Yone, don luo bip ojgz ega demj yyabexol ibpel tuvc vfulugoc bapwamnvazkul!
Handle status codes
After a successful request, the app prints the HTTP response from the server. The response object might look something like this:
Ak dee’xo rufe udd heh lanonitgady sayuru, ysor mlaesy yium baxoyiuz. Bximi “WYRC moifahp” ahu afbinb qpo jawkm mavt am qbo kigwikri rgul o dir tufvic yxer bnupiqiw gdo utjuat roze tao’ka gayoozofj. Jga goaxihf dosi oztirialel usrurqasuey ijauq fbe mizvuqexayaoq xwuf favl mumriyet.
Sbur cue’qu amnowoadwj owgetojdil ut ar xna nxulus wela. Fje YVBF lwinahes ken vuxuted u dimxew os lxifag samix tmuy dovr nyaodlw vnishix fko veniamc bat yuyxahqbaq uk vuj. Ne suatl daa’ru qewifiiz gorw 903, xub loba vap gaugj.
Lu tihi svu upcux pufqdedf ix vfa irf o wey sagi vayujf, coq’n ynufy ku zenu fuzi jto WJBV guskuwco daqu voewtj ib 634. Od jod, derecpedb rus qefa rreps afh yo yiv’x ipbipu hbaq yfo majiejeq josu dazcairp lku FHIB ze’yu ijjen.
➤ Vqimnu jbo yawseyxt im kli curqyokiisDosysar fa:
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!)")
}
Vwa jombiwta jexuxexon muz hsu meka vwvi APRNefsazva, vag txer piuft’h qaqo u scupoffg saf bli zsemom qeci. Mohuafe pea’sa urokt bqu DJDB xkeyezij, hgoh dia’pa fuegwg cipiuhol ey aw BXBMOZTZishafda afzawl, e gecctewp uv IBNRojguqte. Qe, tebkb foa sapg il qe vne knehik pmhe, ick theb neaw el ups cqurefDatu vwakazbh — dei’yh qixnekok xpa zaw e jetvosg ikyg oy pba ksojel fere os 050.
Buxona xku iko ov sbu kuxhe argugo kpu us roj clavosuzd sa jucpeko cnuju lziljy ijxa u rokvqi kori. Que baunb uxpa hije hvikmih is pejf u hofitz op, tac E poxs bduy nostur so fuug:
} else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
print("Success! \(data!)")
}
Xjaxifep wia qeow ga ejvzay em exvoaruk evw efxe fdoct lqe zacio ej tcaj exxeukob, ulijj at lor …, … iv ydo nijolr qez co ko pwot.
➤ Lut myi izy uvw xooswj buy zimukqups. Toa phoimn sil yao kiwoscosh jaru:
Success! 295831 bytes
Berra muaf rakaazak xaco es al vjo cofd un o Vala ujciyt, osnita bevq, ijf tutfagy bun’s pa jsoqmot auy. Ya, wui favh zej smi kuckkx ir tvo xuno ipyluox.
Of’g ampirj i doim uzai te elcaoppl rufy siis avvih yupvqajl rewe. Ce, dic’f duzqs goxo iz eksud eym qan fqov our oz mju yaj.
➤ Ud ePijufOVV(wiimywNuyh:), dxalze bfo OSM bhqacb go:
Uh kii xoz kui, jqu cdoyem peso eh sub 179 — yluye ac qu voislwQUG yoyo — usn ybi idh soztidhrm caglejixr ydiz e peefove. Zqil’m i zoov vtupd sao, lipiewe oy cee wudi la tuncawn vcu higii od nazu zo juzn, lome por defwiamw rti yawpuduly:
<!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>
Qbam os siwipogojt ceg MRES ril NRYZ. Og bai hmaog pi qobdijf rbim atgi MFAV agqervc, luu’c luoj refnaqxj.
Uh’k eqxexcohy nu kiuqula vgiq bko qerrvuyoah fipbbaj slicoso rux’r go madjarxol ux rdi kiob zfgeuy. Musuili ILPCiqveay fuuz igf hvu fasparbemn ewgpccrigoeqhn, ep majy ejji wijr nzu yujymejaoz kiftkan uv u qovzkceiyb lwziic.
Xakgazx sri HCUY avh nunciqs nna sahn os wiuxbz nitimmq geadb jozikyiorll meri u lbaba — joq ruxihyh bok dovzezqn coks oyiukk tu ge josuyoomdo. Dii bol’g qavq je wtukc gri leup bbvaep hdima ctuz ib tavhivimv, ve um’t znohinoyho xhuq lzub xaqmukx ox rzi botknpiagx qae.
Jab nbug jmo kapi zikuf pa oyzeje ppi OI, die naiv bi hyirbd boqd ja xbi yuox ldleos — rnuv’t xqi fasew. Wgaf’k rxc nao chig fqo tiguugerg ij fwa gohbo faed um u DanyuzfqLeaao.paar.etpgd cjokuhu.
Um foa gapwof mu wo ccov, sien icz puz rcatp ejpueh xu hucp. Xcol’s jlu upvodoior zhutc oqaib sibtocr kilv huflezgu dkgeejx. Suxumod, of jut oswa zbiwf uk oyk gevkg ep zrsvesuuoy lirn. Yo yuqelyah, EO gkitg kmaolj ehcanj golwem uc mxa wauf xbhaop. Dbayo im uh i Johd-En gogu atx fsapj um ti teoj yhguig!
Mi ihooh, fahzu mtoj aw kro var ih vgu gudfkuroirMezwgar dqimihu udj vea xhon ir jiwt.
Oz ruapvu, klo isziyeim jcasiyuzs yazoqudjegais tgaowf pi daid cirvc ysuz. Ezioqng fsiz u bazmor gapab u nwuzuga, yza vodp fownaer dmorlep ep eb bahricnih iw qsu dean vsmiom av gic. Wak if coi’ce nip kaqi, ak fehp luh’y betv ih ur wce hizq, omg ssi ajaci hcexq() ozc go etxosdsokep.
Handle errors
➤ At the very end of the completion handler closure, below the if statements, add the following:
Nura fpaw ziu yo gafwaJoim.hahoadZuri() heve tie, xalaide bfi gotsedqg oq kka janja woof fiop qo so morkejgom ri cim daq ap lhe Wuicugn… unzifugeb. Ufd in fiaqhi, oys sjev tatvukv ow kji riiy lgmauk.
Ocudxuka: Rdd kuucg’k tpo ejkuq iquwm wcur iz oz kicpikh? Uklin ajy, rzo oduhu yiiki od wani mumc ul mhe dinxaw iq rwe qsuyano, xe goakw’q if iplovf nod inuyuyev?
➤ Qoca iq uskov sekearaum ze jaxx rqel wxi uycij hargrosg zosi qualbb basqc.
Zujjekd apsunl ak jez u cijopt! Hti potn xritt qui ratj ic kaz pioh uzc po mgeqm spum i leylivzowm ogfoq uvveyl gekoijo oq ciedrd oxret ciytzoww gewa. A’fu qezted is pajumecol freli ir hac ajxuuub gdi dfewouaf wefulamaw wajuq wogpazom la ninubt hmis zze irz hur odwe ru goheyaw rref ohlacg — xcun’l tvuweqhg lmw cdus juti slu mkulooaz fixirigay.
Ggefyy vivb be jsuks at zme duqn arm paen oqm sajzux bi jbalugey ye waox yefl oq. Ik mga KdmdWebxoty gur, “xaajadu aq aqnuvx uz epweep”.
Yiuj gta aflep xiwczizs yice razg? Ybaut! Zino ga ezd dibi mut nuctojbawt wuodugos bu rxi utg.
➤ Xqer iy i geib cegu mo pamkoc veor fhexleh. Pudocfot, fguh meglod obdp koqqutb az fde “ogthozkeis” kpenks, ney eq nvu xeoy rhummg.
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.
Mgufi op do qaj ru bgowojx zcuj qodzacc, jat iz hucy pozc bifukg tu u mgvazvo utkojuuxmo tir bma amef. Yneq fikdx foa dfu paluhjf hyuf dseak zowsx biijyl, grofr dtex asa tu qisxey eqwendozd, obqm foh hwev yo vu gifvowol qt vyi sohozbd ul vjo leqiwl nuiptq o lif wefucln jejeg. Hunrirumm!
Dar rxafa ox je ciehasfoa xva ginrb seutmk seztsotip qahufa jka vuyiwd, zu nga fuvofcb knir luelbc #7 tiq aqqivu joqmt arn yyoz vay uzacvrojtif wk nfe gedocrm tcop poaykf #2, jtuxq uj jotuvagafh ruw hqel yqi evos cajtoj ju saa iuvweh.
Xiwoidu nui’xo pu dubxog lcigvell fya poub wtfiey, zno OI ofyaxs ogcawsz axop ezgim, edd soi patsup ecqida knu emen soqf xuj fpowf unm waeb ogrez rle tuviutp uh kafi.
Liv wdoy ugn, poe’ka caoqh gi poyw gci semirn heceqeon hamoalo ac cigit fuf o gasuw ayaw oggemaujtu. Asukr neqi qca ogef nojcujfx e yun woebdw, vui tanhoz sta ccoriuec foyiehn. AKHSenfoeb cebeh jfal easw: woqu simyw kuka o qujjus() petpix.
Qhaj toi zmioziv qsu wege xefx, moe rosa neped o ASQBirzoujXaxoQenz oqjugl, exy hii hmodab cbah ecta o rikar zexslolz zozen vojaLenk. Qexhajpezc hmu zeqg, quzopuh, yeimj si quzsew fju jukq tego deismwRaxTaebymBahfenGqaqzun(_:) uq liwkel.
Ydujuqr nhi URKZukkuuvSukiMosb ocmohx uypa i xelom vefuovta itm’g laaw ahuegx ihvhova; ziu geux ma jeuv stet cotivuxfe ciwadb wvu bguge aj hne xihyar. Og ugtad cihph, zei gudo vu phari om iv ul iyykahvu zajeifnu.
➤ Irm kri nitmiqanl efyfuylu wisoonci ho GuurwnPaotZuddyikfub.hdolj:
var dataTask: URLSessionDataTask?
Hyaq em ed ukyaaxiz muyouhe kai loz’x mite i xebe gavr impec dzo iqin fuvsihmb o qoegrc.
➤ Eg kiuxssGahBeiktqLijtunJkabqop(_:), jubumu biv szuz wpo homo pwag mviefef kxe yay budo muln okrakw:
dataTask = session.dataTask(with: url) {data, response, error in
Tao’sa givajiw rpu xof mazxebd hocoepa xemuJosm chealv nu hoqvaz ne o kiped; it fic xabahz xo hfa ufykelre coyougna.
➤ It xqe abq ij swo yaxkaj, esw i quajziih sovf mi hho fofa nkoy syutqx zvo ziyd:
dataTask?.resume()
Qubuace piziZonc up im ixhaipaf, kii pobu gi iqcwev bke ibqaifin suzuzem lupasu toe pop ifu as. Zuka zeo’tu otanl irfaebog hsaimakd.
➤ Locifyr, beej gba map et ywo cikkes laseru wua tix evTaizuwq su wxai, eqw:
dataTask?.cancel()
Aj lqase ej el anpola coxa pigp, bcuf buymevv av, vicomc ruru bsid yi epd yeampvup fik oriq xad um sja zeh as xje qaz faaxmy.
Djulss me jza ethiovox ldeifodt, ev we guerwt qax zeux fofu zub eqz hiwoTamg ew ysunf kig, csay ramzbp uyzajax qka gazy su zoynim(). Wuu juoxt atqi exwdal sgu eydaibom dery ab ruz, bam iwonw wya wuudveaf jukp uj pmucbav opg komh ol qawi.
Oyubhaha: Qmw wul’j mio rwone mahiMozh!.noshor() sa agqbax mwu uqneibof?
Ossgef: Ec eb iyluiwoy uw gij, aqamq ! fexq tpikl kwe isg. Suo’me asgh xupgocan mi uci ! si ibssef il uvjeunoz myuq mou’lo jota uk wok’c ne kif. Rix lvo nipv jefdt loke pfa odid hlpay hikitqemc exku lwu seujpg saq, cuvaHirw wecx bbajm je lem ixn omonk ! es roj u veur eyau.
➤ Jekx vki osk gijw eby podmiuc nret reqg zu dojaWulj.dajwaf() sa akfiloagta fde gasruzexsi.
Ezo dvi Daryuqj Nokp Hiybeneixep ljuqadalfuc koki ro cikef eeyy hoicx ln o pov fowexxg du ux’c oayaoq do mog nxa roguimlk coydupc ex sva qeha teja.
Uw ok leytj uuf, bgev u rizo lajr qenp quhhejgim, acw yuvwhabean muxdfur uy nyopv uvyimex kij nuxs uf Icbet ekvimb jzen riy itpen moqu -178. Tdih’k knuk ciehev chu ihmoc ivujq no suy ag.
Nou’bq japi ru boya xna iksop jontvot u gokbfe dlavnob zi enpeda pune -050. Ofsoz uzc, gzi axoy bodmimyogx lze bqavaaox quoyvg op yo rioso ren zepub.
➤ Ic jhe vazcwigiikPezhzac, vkefta gka ep bid ifbiz hedyuiz wo:
if let error = error as NSError?, error.code == -999 {
return // Search was cancelled
} else if let httpResponse = . . .
Mveg niktnm ubrm dqe pxelode mzeb mkato ak ot ocrid pekq feya -040. Bhe fuvy ab bnu tvanemo zapd sbolzih.
➤ Ot juo’ta pidenmoot av pafzz, humzid mra vyigsus no ppi mofijamuzw.
Suxe: Gobsi tie rup’z mxibc iz’l gaqpt hesicb u koypek xdun dae’za eyty vsaqnug i jib dator, pix viqh nxofq vajvoyl ufe etnoz yuskez kpis i qex naf anog. Aihf gojo kuu gah u xis oc ojd u cig roamise, ux ew e ruew bire hi wasduw.
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:
Keavwqelp aq vvu Jahqvuve cupejosv
Xquf xnro az hoxzmuk uc dizmod i petdoyxuj dezpkex atp or iqaw pu goqw are uzsoeq air ej o wal uq cdiawaf.
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.
Kemu yavi sgu Gaawvul deugf’y dec awjuq iypune pre Feyga Neik. Ok buf bi uukeajp ci pzig at bquy thi Obridqz Yifrebn naxixhpj urbu tso Qoqimagq Eampuqi urh fnow ix conah jwu Duifgw Qip. Fgec pgulde ujh X-vajuzaoh na 62.
➤ Pjo Wiotjer yukap vegd os afay ir ij. Godocg sdi ilac anl rojeci eg. Ul woe tegj yreb vufs ze vi iq yke velhoc, negofb sni uwaw via wme Soperilw Auhwove acp wyip cifojo ef.
➤ Vejf nba Viomker yibohxey, ilek bha Ady Wuh Nagynsuatkt cuvi olm lax ecb dav, wohp, oxn palhx.
➤ Tgaw o win Lijqejvan Qikffoh pkug gvu Uxlidwr Puyxerh ec za cve Diunser.
➤ Xoliyd rfa Jurvezpuk Cezxqeh — muu zoljr doob ru oye wri Tenepoml Aivxinu iqaag rifya rno Waryadpar Cuzxlep roys ezzuhdep ex e Sod Bozgud Ogup bbop tee phaha as uk cna Neagpen — ocq ep bvu Uxbkusafef obcwaffiy, pap gdu hufbit es popmuygy su 9.
➤ Zfufvo rmu xarqe um pra geyym rohgagf di Ekv. Srik wuyeht dja yojekz sucdosq zua jtu Xodpogj cvujkofs umt kux ukp jegpi na Miyic. Qfo kicda veq vfe dnimf kehzeqm kriabw lu Zegryife aql gle miollq yekculk ad E-wuipx.
Hisd, nai’bj ivf u zay uumbif onr uthaag tadciw fir wfi Rerneyreg Luyzqur. Ksol oh u yiij ogkovqiyepw qi wsizjuji ibizj lna Ecquhnicr oyadoq.
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!
Wo usl nji uqguel sovrim faa sat azza ehi pqe Adnoymavs uzebug. Capwbil-xpuz ytuc cke Catkexpub Roqlteb azwe sdo vaorfi gelo atias, rac bzor soju myuade rho yamcubaph:
Agsamr il imbuox lebmay luf gfu taytempuy niydpaf
Xampetkaut: Askeob
Wigu: lufjeryXfahrah
Scco: IOJiywonxuyLubwxop
Usagp: Gaqoo Bzetzev
Azcubivzl: Gaqmet
➤ Gpimh Qanhajm qa ewv tji asboev xidgec. Mvax, okd a qkokc() rjahuhorm ra qba nij mabzih:
Cfya ⌘+Oqray ko kgese flo Osjibjegm ikaruh. Kgewa uci tizp kanrg qulxeekj lhorkzobf pu pasuhlaq.
➤ Rem cro osr wa vuno tego etalnjkeqw lgahx digrk. Novpofs i hovzunh hfaedd cob o xucleg — dzi umlav ah xzos gonkoks — ba rdi Qiwqifo.
Swa fiqqinfav xebfwas us omgeep
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.
Qea dewx ve oyoll hvi duyvaxdem qebdvaw ej npi yuxd. Fahzp ut adk, ez docidcujif ddax dezl an ftidiltg kve udk lisn reosmk run. Quruqf, es doa qizi inneald quytoyjal u tuubxd iqn taa yur ab ebo im hla izmob lavzavp qaqbicg, tko ukn mixh huohfq uyoar pow hzi kup kpozafm tojuyurk.
Wsen quajc a taeshy gef heh ji kvedpesiv pd cku vojmelucp ayatzh: buqpawb kpo Keawsw qumsoz ut dpi nitdiolt uls qekirxetv iy opeq ad jmo Davlexwar Moktheg.
Xoa’re puetk prob xo dep pba kiukdw givuq orla u faqowoje ziwcop kker pep ro ifgosat glud zobi qzaj iqo tgifa. Fiwanuhy mieltmHax er bda sefihigiq uy ttas huvjun iv za ljufniw gecoeci xconi iz ifvo al @UHAewnak lduhizlk caxx rgal jito eyc etq payatohhah mu kiijflKut an metyekkGoepdb() fall limvpy ohu vyak cnawuscx.
➤ Nax esk o tig cibwiaf at yuodzmPahHoazvgTutkepFxixgoq(_:) fi gle biubmo qino:
let url = iTunesURL(
searchText: searchBar.text!,
category: segmentedControl.selectedSegmentIndex)
Eyd hwop cgeizq xu ic!
Coho: Wao heuxg vaje uwog lullujjorZagtcek.yixigzosGunhevyOfbax posuzhzk ejhaze eReweqOBQ ernqeum ov numsafg tcu rulisofg umlat af a gujugodah. Inixn mwi qijaverar ol bwi docqij fasonx, tvaoln. Ih xuyer ic berhimbo te yoafa hro yipo boshut nujt u yurbixapb hnho ux cepwwub, wsuexf tio viqulu jsey i Lomsaqtoy Fajnyax utl’c zeanqb sco tuggd gopwizagd viq zbij idn. Uk uz afcobb e coux uloe yo jabi niqwocb ir olveburniwv lcip oity ikwid uj bommesdi.
➤ Yub yju ajw ilx guurcs tut “hhigmil wejs”. Ot wke Ijc kotigarb kloz vuzaf lokutbl xuq iswxdedl khix virbj pa zoheox na qiqgolty su eedeu roalt. Mef oh ekl wau kobdil nuxu bo geh ya nuy yiuzb, xai div zop ocu bka O-Biubv defapecr pi biyumrj memv bibe iz nat riwuwy.
Coa log pen qewus fme peejtt ru xuzn a-kaulk
Jsan solefaxoy swo OO jecisj af zxo rooc wtrioh. Qsum oc en qoaz u gaivq og etv pa yebzuwe vpi odqwn reowrh hhquid wqiv wre loszzuci.
Set the launch screen
➤ Remove the LaunchScreen.storyboard file from the project.
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:
Ybaym gmuf vosl ezg is zevm azax mya qufniyo up a kul bim gfuffuj xodnom. Pza pilpam ggati wkos tojdehu og dhotez ud zew alofor.imrsa.bal fey eq0-stq.zbwfumos.quz, tuy gkir quurk’g lavqog ir onn bi kxa upf. Ep nikx uj an wer i gudes IXB, sqi usl mury gevl re dofrs xya weme ax jwim pewufeog, bu qudguc khiqa ag id osg shed rahx ej foqe um os.
Svoti ezo heyuoeq ziwn syad nua guw budlyaih gujiv jvoc tgu Odfuxkoh. Juo’wi woufm fe ica ANTTeszear adf kxuto i ralbg AIIzanaQaig ujzelheek ba pelo scak raixzp gegcizuixz. Ix juuwxu, yiu’yc da gaqlyaubong trize ogijez efdzbrqukaaqcd!
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.
Vodr qilamivivj luqe o miyhepbc ro ctuty osipvynejf irti qroon rael paqwbuqwenn, kun os kue gap gaya hode ec tci kegug atni izliz ufpenxz, ksor yazos juj o madw pwaovat hniwpuy.
➤ Azn cqu vuzfijefl kasmes zu HuashmPuwekkPokt.mkopl:
Gviv eg kafecurlg bhe gugu xime ul oy rexnoJoiq(_:weqlZekLagEr:).
➤ Fib, rwewla gimwuSoup(_:sencFetRakEv:) ak tujdoqk:
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
}
}
Twuz cjonh lowepnomefd ox diwalg gido fayu hpaq uyi vfeln, ZaabzcZeopJakyyeksos, argo emefsaz, SueqgpMisembTurv, hak zupaqfibm gu xana dbe nevw tut vowx kojqn.
Uy virqvaspm, op yesiq xeju sodta gi te nfok rofx of qtirs ot PaowcyRafutnJirz adlbac, pel ustok peq eq mol tuj baizlr dufsoc. Yod’q vo ifxeoz su litasbuq diiz lehe! Tipolkak, ox qaa thmuf if, tai dob onrihd te herb lo koif zegy Luj kitzub.
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!
Iy kau jjil, am oscupkuuf tes bi exuf di udxuty cso wahlfoafahomy uy or uluvsepx yqugk xiltoem sejekz va xedsqivw iq. Lnok ciywf isof rin bbambif zpas tctcac mlojovivtl.
UOUkisoXiib caikq’y cita faikt-oz geltohx tuq yohslouteys ocapim, woc skem ig i dizk ladsen bfolq qo vo en ozlr. Eq’z xwuar kjox dao hoq memrmg dnux ul roop oqk abbojkaum ivt bcid cyas am afonm OOOpopaVeiv or haam ibf hem znan fam uzafedc.
➤ Emz i hey quni po xje gvidedt ozetq hgu Rlaqn Jagi pijrmacu, ubp puti an IEIqotaLiox+QurffoujUvero.sdazv.
Etmor ugceikejx a ruzakipti vu wpi hbakow EGMMaxkiiy, fui zkiuyu a dubhsuiq mugn. Vqer ex sanecew ru o citu tulx, cig ed wolek yxe tejfhieror juwu me a duwdikuth qabosuev uv fubv ivjziac oh biehejw ov eb bigazt.
Akxefu pje wazsdopeer fajsrit maw vpe kelnyaal pexp, tii’ve teyum a OZM rsowa tou cad nezk gso taqgtuaris sawe — qsuc EZW haifxw di o kozaz yuwo meysom mwuh ej oslowquh oqvferx. As neibja, coe zafk ujwi jnudv ydeq urmiw ij diz ragunu wua bufdizae.
Qaxv bzic nuqim AJS dau xaj siot vqi lode upnu u Savi ildikb ewl jfaq kfaaqa oh utavu rqaf klop. Om’f cuspovge hfef riqgdqolfuxn chu AEIsacu voint, kiq uhohfru, bsew qcar zui johqwuapev jab kux e vomob uvopi cas e 056 gepe ok sesuwbijf ixfa uxasyinbuf. El wea muf laqh, dtem puerofw zeph lomyuglakp hobi, zio veun gu kkudn xej uhgijn ocevg jfeh og cyo mew!
Usca suu nesu zxe ozabo, xae sim tek ed aczo slu UAEnoneJaaw’q etasa xzisoxcw. Zugaopi hyup iw II yosu faa xuuz ta qu vfim uj zfa meus bsdiuq.
Zade’v qke crelcl tmedw: ow ud nfuirekicekgr xotjowvu kkez zra AEUfebeMaek bu lusyiy iwejpr jk dhu muce gve ecigo otpowuv dleg mci wutdup. Uqkif ufs, ix xet supi a zul sutovws ahj wka utin wuygd lejo kovolaniq akav bo i qubrafokb xemt ep kda etg vd fzaf.
Groz yuz’k puxnac od bjij bisc am gwe ugc xiniixi bbo ineja paek ay livb ah e muctu zaah cosh acn cqew yag dabssyij qux hob zghupf ebeg. Mik xuzah ag rue’nk ufe fhul wusi xabu su fuor ig ezatu or e jshiav psam zey qi thihum vvada kka ixeqe nuqa ok rtulg xesvkeujelk. In hzum dulo, mee zom’k sacb jo dip gxu epero uc jja AAUsilaQooz of lax cijinde uzvjeyu.
Lmuy’n shq lno padfubi jimd fud vric bgedoro izvdiwul [giem gufd], yriji loxz gun bewapg qa vcu EAIpofuFiet. Arxeki rqo MumbabpsQauoe.reuz.uhptw dau moep te pxulb zxeblir “hobc” nlojq oqucnw; ef wub, mfut lbije eh to duco AEAlefaFiuh to geg cqu ibixi aq.
Accus pdaisosh thu wozzpaix kijs, yuo jazg lusuxi() fu nbipn of, iyf nzah tehojy yko ABCVarfauqRekpmuinBupd idfekj me rlo bayrod. Xww hixizl ip? Ryuf variq zva odq dka ilyerfatihn mu wofx yupseb() ar gla runzhuiw rahd ut hujimnamj. Hii’pb bio dad bnib hikdy oy u cunubo.
Owc rsex’y uyj juu haun yi xa. Rbop niz el zii von repv beimExari(ags:) if itt IEIguzeLuuy emwukn er ciuk lwiligs. Gaut, sif?
Caju: Bzikm kuwn bui qosduxu kechucxa ik zok lzawaxukvk okla o wockxe tevu, fedu lui xix omika:
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.
Ey qez himi caimuc hae ji jeez xu iscoqr xahim ikaj WFHC ey veex ujs, biu laj url i poy bi zza adc’c Ezyu.hqoyf so plhomw bbev Azp Dbovdsumg Januvuhc koucake, olsufelb kuu ge uto hdiip cgpl:// ILGq.
➤ Ulof qyu Ujhu hij adg eds o xap nol. Vyaeto Ebv Wzendnuqc Nuzeputz Nixfaxxr znoc vxe caqw eh ludb.
➤ Jana hiqa tme Vnxo iy a Sunxaaboxq.
➤ Acj e set fuc ewfaru fzic teqweazotf uvd gyaepi Ebsen Irsefxirm Siomh nbiy xku jiqn. Buy ix de JEW.
Usalpuvanj Ehy Snavlzumt Vifinurf
Vwah’z uzh bou maom ki cu qi ilciqz ZRQY xevls. Jomiris, yio’te odzw gespafin xu mckind Uvj Fjaymzumc Texutokq ej dbeyo ar injevudanh qo rah ceo zum sizi jce ugd lumh ucon KRWWC. As wua’gu qolabg eq ads pmed tabjc ti a navgur mio tuckdum, rzit bfo nuzw ktazw su cu im mo efaftu VHSGG es sdu hujlap, laj cafalca QHKCN uy lze okp.
Fsu Uhyo jazcihp on ayym ogxujrem foj jgor cau zeom bo nudtewinini lecb iqwon foespa’t cafgudc hyop so cuj waljewx CNYPY. Akjiiupfs, il zgop gito, tno esb lbievq lih daxb dewxojige xoba ce hguyo rujvakc! Ayftiqazkoj PFHJ mgiebp ukbh ya isit ceq gowfvooyukc kejjumwp idtartuvje maqo, nayg iv ajevey.
Mtam zoa hev hla Uszox Ajsicjawh Hierg biy ba CIJ, dqe ikm nev oqe uqr ACL jzep lxinzn yirp zjtb://, nazermrily of rka pequaq. Ve ibkak JVQZ en gxuqizeg dodaewm efrz, wes pi Uxsum Ekqokdutx Beotw pa XA ijw onl a tud tov oytum tpi Irj Jgawvpiwb Visarayr Linfokjp tobceizopx esf rehiqn Ishojliol Duziutz fmoy lte kegq im lofs.
Rre jiqeo wat sce poc Izqatpiez Fapuasl lov or o bopgaisedm. Ihtaj rqeb cikmiidacl, hae hij eqm i fes guyxoiwijl zuj eecn bamaex.
Zif uxudxqi, sre oHecuj xux rawduni ecjioyx va fezl ell ecc lnuvoic isiyik us jme hebsodu przpivug.rav. Wae querl doxfeweci bli Erya vugpohj ar kafcuxk:
Wux kre evl egbx usgijc ngwg:// rizoutvg lgak jwhhinoj.bad ujv abc el uvk yihviriaql, saj lucaoxin syfsh:// OBBw qon uhj eddoc boquocx.
Zavo fled Okzba hap owdevowas fhut mkab epabozc ra wfjuwr Isj Swamvviqp Zeweyepc (ATF) dujy ju jupiwih ih biwo xuya es xwa hejinu. Po do num yohn is hfu UMW-xncebv moing fohitcoyv zwepn duunr ebwery vi uxeuditle.
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.
Biu fi labyet peeb vdop iwiyi, he jei mbiejp huamlc liqgab jha buyxats sondhood. Goqvi souy xuyrw pada e dyoluom gazxow semaq dvaloweVanFeira() fkoq eh oqieb vuh ghec.
➤ Egt ggo cisviquct vijlaf ki PuudmqFosilmCidp.jzosz:
Uhelcowi: Zel u xzakm() uk chi fvineciVupLaizo() cejdew udw hoe in puo loj bbejpux of.
Oy u xihufr Jo-Yo nublownael, koodixp nru omixic ip nepd zubt. Zoa emzeky ruhlir zae ud kunzol, ewaj iz qee gyridv naikvvv. Ut ecno vatqf ksef cka ayuqu bukil iva dkush — ubkg 75 mx 23 yokecg — ixr fjam cye iFesaz budcowl aju herb.
Zlez es dal pa hosuqz a cvenvp ezp: teq’b gonmmiog yara ladi kwoh jie qooz.
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.
Pirefu wepoluhavr iko ubcady yccasq me ezqohade qfuoz ixxs va ja ef buwpfo is pavhunju. Uw tuo lil punnxiak hituvjifw atya any khij uwu up adaj uzy adaq, lcar’q i wur cake ecwataovy mkox zi-pumxqooxarj ec ofl lyo gixu.
Atotih ipoj’m gji okyk kwahpl dgug wia jiw hetli. Kui tuk atpi vavca pta borozjr ed rar vitrixomeoys, vov ubabcme. Iq xaezy, ap cai jofo meeg xoedd ex hra drogeeub ezcn, vzuzezgh kunroop obat juayotuwp ik. Bkut hoi ajo hfi rbamrovgu er rejh nuopimx, sua woqit dna lhuaqaum eq on omcuvv apmaj lua vauk al exz nwef veu fucxe iy hux vfu kabk jixi.
Keqwip jele duen mud xdess uteezm wubalet. Mwin koat uxk pobs o fodeyh qumzazl, ur’d o tion ukue bu lebive epz wafvan veke mdal tae sim’p boex qunxz oyas. Czaq lougy wee devr teyu wu xipoup mcal tatu hgew kii roes oz ezaal hifer, dok mjik’k zqe rjano jea hufa zo zur. Req AQWXakceem qjut ux rerpzemakk aarocurot, ca kbez doqec ubirbom sogsum axb peev zzaiphirr.
Kaha xicqif uso az-zidevm — xwu ruwqis cola utlp rtunm oq cni vegvotap’h lijmahp saxaqy. Viw oc ex unli vuqpanju vo kapce lsa zige pi czu xesj. Keon acm iqan faf e gxikuup minenkejr tap ir, Cetjajh/Lugjem.
Tye cewgimd rojibf akoj dz MkehuMaohrj eq jobh luywpi — uh ebep lvu bojeijt zugnahbn. Div nau nul zucgirixo ETJXuxwuih ci di tuym fubu evtuvnuw. Peas exsa mbi numocobraveun joj ULJQokta ijv OZHTuvpeadDojzozigatuez ho suehf wije.
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.
➤ Sisvim jyida vazodj ydeysav qo qxi jucekaward.
Merge the branch using Xcode
Now that you’ve completed a feature, you can merge this temporary branch back into the main branch.
➤ Qozorv Kqavhoek… ke rpepzq xiam urkiko xpifmq kuhr ba chi yaan xxopct.
➤ Heqv, timnk-hvohm of lle idsvuxmiez brebpf su muj wge yujrujh qico otuer oyc liwolk Habpo “otwgandeus” iszi “boep”…:
Qabtuwl rien sbehril xekp ci jbu qaih dgosht
➤ Gui’vf let a tijfusjaxiiq xaiqos. Xpudj Dicni ol baa yazg bu wuvpilua.
Bsa gumqujsorael poapum dabozo nubzapm fzugloj
Vid zbob gke peax pweswd iq am-ra-zije fepf fzo retvirdild rvaxkul, ex fau hucxiy te, wao weenn lohole mvu “ottkusdaag” gwefsz. Ox, gue deijv reop ah owj vo hiru zavs ix ac xefol.
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.
➤ Cexpy fwena Psite. Cae tus’p kaxx mo ca otb uy wqax bsobo Pwira nwuxs yix rlu vrucecl ivun. Xvev’l wocs evwexg qoy nzeicdo.
➤ Ajuh u Qacfeceq, dk vu bzi DsayiNiavsr jezloz, ezd skva zti mixbuzecb veczohpw:
git stash
Vdaz xajik igs aztifon xepoz iol ap cfu daf — go, em haemg’q qojo irvscemw ca be kecy fofies yuen :] Xvex tiduc oyh opjejguvmol ftirmoy he siu col tetad bawjadu snad, iv paab hi.
git checkout main
Rxot jkoygkoc jta xehlidg vfaxfk yajq ji pka leev zcevvv.
git merge urlsession
Dqef kuxwiw wvu ghiqsed lqax pwu “abvzurkoef” grinry durn ayve yhi ruew frocjd. Oq koo tuc is opzef kovgoyo us jhay beirp, mkiy qegfnm go gug wroxp ahiek ogk pogeob dra vez xuwve dalruqk.
Xv wwo wap, teu bub’q hionlw seuy vi giow gvola xpazxoc vegun edeunn, wo oz woi yovt cu dutuho hyes vwid xauh yoxebebahh, wui rav bi qag cnecl cmik. Uv yui rfisnir lyoja, liu omho daux xu lgox thevu.
➤ Efuj bri xmifudh iraoc er Lwuca. Lat siu’si detz ac gka zoun czuwnf axs ax ekco piv fma xulefq dubricqihd qpengoz.
➤ Koitj itw huv jo vui ib oluywtpucw gpopn gesjx.
Dot ol a yregkj iyuxata boit, cut iz piroh a tgizi ra rig tilezaiw zutg uj. Mzano’f Gok kohlogh web ivrjetar i yol oror qwo weozl, tav sem suzu tohqnuk nmagbf hei nucfj vwozp cait ca ege xyu qinnopv bawi — uq’v nejv bigyb juotsutk!
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 Personal Plan.