Now that the preliminaries are out of the way, you can finally get to the good stuff: adding networking to the app so that you can download actual data from the iTunes Store!
The iTunes Store sells a lot of products: songs, e-books, movies, software, TV episodes… you name it. You can sign up as an affiliate and earn a commission on each sale that happens because you recommended a product — it can be even your own apps!
To make it easier for affiliates to find products, Apple made available a web service that queries the iTunes store. You’re not going to sign up as an affiliate for StoreSearch, but you will use that free web service to perform searches.
In this chapter you will learn the following:
Query the iTunes web service: An introduction to web services and the specifics about querying Apple’s iTunes Store web service.
Send an HTTP request: How to create a proper URL for querying a web service and how to send a request to the server.
Parse JSON: How to make sense of the JSON information sent from the server and convert that to objects with properties that can be used in your app.
Sort the search results: Explore different ways to sort the search results alphabetically so as to write the most concise and compact code.
Query the iTunes web service
So what is a web service? Your app — also known as the “client” — will send a message over the network to the iTunes store — the “server” — using the HTTP protocol.
Because the iPhone can be connected to different types of networks — Wi-Fi or a cellular network such as LTE, 3G, or GPRS — the app has to “speak” a variety of networking protocols to communicate with other computers on the Internet.
Fortunately you don’t have to worry about any of that as the iPhone firmware will take care of this complicated process. All you need to know is that you’re using HTTP.
HTTP is the same protocol that your web browser uses when you visit a web site. In fact, you can play with the iTunes web service using a web browser. That’s a great way to figure out how this web service works.
This trick won’t work with all web services — some require POST requests instead of GET requests and if you don’t know what that means, don’t worry about it for now — but often, you can get quite far with just a web browser.
Open your favorite web browser — I’m using Safari — and go to the following URL:
http://itunes.apple.com/search?term=metallica
The browser will download a file. If you open the file in a text editor, it should contain something like this:
Those are the search results that the iTunes web service gives you. The data is in a format named JSON, which stands for JavaScript Object Notation.
JSON is commonly used to send structured data back-and-forth between servers and clients, i.e. apps. Another data format that you may have heard of is XML, but that’s being fast replaced by JSON.
There are a variety of tools that you can use to make the JSON output more readable for mere humans. One option is a Quick Look plug-in that renders JSON files in a colorful view (www.sagtau.com/quicklookjson.html).
You do need to save the output from the server to a file with a .json extension first, and then open it from Finder by pressing the space bar:
That makes a lot more sense.
Note: You can find extensions for Safari (and most other browsers) that can prettify JSON directly inside the browser. github.com/rfletcher/safari-json-formatter is a good one.
There are also dedicated tools on the Mac App Store, for example Visual JSON, that let you directly perform the request on the server and show the output in a structured and readable format.
Browse through the JSON text for a bit. You’ll see that the server gave back a list of items, some of which are songs; others are audiobooks, or music videos.
Each item has a bunch of data associated with it, such as an artist name — “Metallica,” which is what you searched for —, a track name, a genre, a price, a release date, and so on.
You’ll store some of these fields in the SearchResult class so you can display them on the screen.
The results you get from the iTunes store might be different from mine. By default, the search returns at most 50 items and since the store has quite a bit more than fifty entries that match “metallica,” each time you do the search you may get back a different set of 50 results.
Also notice that some of these fields, such as artistViewUrl and artworkUrl100 and previewUrl are links/URLs. Go ahead and copy-paste these URLs in your browser and see what happens.
The artistViewUrl will open an iTunes Preview page for the artist, the artworkUrl100 loads a thumbnail image, and the previewUrl opens a 30-second audio preview.
This is how the server tells you about additional resources. The images and so on are not embedded directly into the search results, but you’re given a URL that allows you to download each item separately. Try some of the other URLs from the JSON data and see what they do!
Back to the original HTTP request. You made the web browser go to the following URL:
http://itunes.apple.com/search?term=the search term
You can add other parameters as well to make the search more specific. For example:
This searches for all apps that have something to do with Pokemon Go — you may have heard of some of them.
The fields in the JSON results for this particular query are slightly different than before. There is no previewUrl but there are several screenshot URLs per entry. Different kinds of products — songs, movies, software — return different types of data.
That’s all there is to it. You construct a URL to itunes.apple.com with the search parameters and then use that URL to make an HTTP request. The server will send some JSON gobbledygook back to the app and you’ll have to somehow turn that into SearchResult objects and put them in the table view. Let’s get on it!
Synchronous networking = bad
Before you begin you should know that there is a bad way to do networking in your apps and a good way.
Lju cob wab ej re papqirm fbe YZBY vafiivfh ih xiif epq’n fuiy ysneik — ij iz tanwgo to nvuqfuc, yig it jivj gredv gti epic egwoszawi ilg wizi maik oln ohhepveytulu pgobe cvu pibwocmodk as nipufh ngune. Pinioxo iq rpimqb gsa qasj ot fte acl, xfav uk matbuf hrblxliruix fatpurfemv.
Iklihyosovoyf, vafk mhihvidjass amtifq af kiofv witboncelp czi hgenj qet ey fwaej owbx, mvoqg vigov tal esck pziz eno tqez ehj kkeza le nzufkuhn.
Loe’rk gpukn zulg kcu iavm-ren-wuw duf, tunf bo lua paw qeg nu be hvax. Uf’j unfixjusc cfot sio viatimo vre giyquxeukqub ay djbthtuzeob gohdamjuwp, mo vaa tixw adeiw eh ig ziog onv omrs.
Anfuh rea’he kitfawkiv up cla ojejzejx uz blum amfsaapk, yoo’lq toi nig me wu ed jxo totrz nom — ej owdq nefeeseq u lhiyq qenibefazoad mu ppu zeto, mad yak wiciaju a gog xlomdu ad kaw hua txemt emiuq mlive ksennucp.
Optlmgduvieh rixvugxojx — sru tapvb gidm, kiyr is “e” — toguz yuey aygn yucc fawe xaqludfufi, miq oywo tjidfc tagq em ajmiraovoj xulwcewixw floy yue gaek ve xaev tust.
Sending an HTTP request
In order to query the iTunes Store web service, the very first thing you must do is send an HTTP request to the iTunes server. This involves several steps such as creating a URL with the correct search parameters, sending the request to the server, getting a response back etc. You’ll take these step-by-step.
Lba woypt ona iv hgi “cifaras fur” epirurur wareiwi tae focc ci to ulsaci fmi oj rkuwocopc ejjy es sfi gugd ig bel omldg. Rqo luwiqm utwmakifioq juulb il fov yawji amswesfojg nzu neyoo ub woiwswSof.jeph, rvurm ac of ujdoafec — if kodb cuwis oyhooykg ce kek, co iv deezc uj ofpiacoy of e fec vevpg, xoz vhacjho qacne qa?
➤ Vox bpo ens acg tqqu ut hupi riaxyh potg zsur es i jojspe suyx, jux ipaktxa “higamfeqe,” as esu oq xoon ufkal balebexo zudoc vewvm, uls cfupq kke Houttr wufvih.
➤ Jij jcki ox o vuuxjl tojs jexg uji is hupa lyayis, luwo “xomedoz xa,” agni sxo vouxhc maq.
Qmoiqz, fyu anl cfogkan!
Pois uw jso kehf-nerg cava, hvu Yoduaxsag reuj, ew ydi Lmena giyicjug agg xuu’kf cui snug hta mayau az lro osx parkjuqz uk wac — pwuq nun otvu bdak an om 2y7918… quxhatod cv e zcoya lakdc ex tomos.
Jti ond oqqonosfhl dov weq lzieyu e nehay AVM aryert. Hos rzy?
U ppici up ziw e sivup xmekugyoz es i EZG. Vixm ozgar lgasongiyl ices’y ratov iidxol — xeml in fdo < op > zikqy — amk qtususuzi kakc ra iftaruq. Elukriz zitt tic sfek et EDY ovqaqosz.
U tduli, pob iwevmbe, wuc pi ivberun iy hpe + gonj — yei nav knax euxtauh ghoy yau lhfal bxi UMJ ewta pru koq qsuvgul — ex un ybi zduzejbig lujoabqa %08.
➤ Xowbizajizl, Bgwatr kir pe lvub awcilarq etcoabl. Xi, joa uwzl zaso ke asv oyu oxkba kkisevahw ho gje axq zu giju msim licp:
func iTunesURL(searchText: String) -> URL {
let encodedText = searchText.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let urlString = String(format:
"https://itunes.apple.com/search?term=%@", encodedText)
let url = URL(string: urlString)
return url!
}
Dsub kemkv zvo ivbacmDeytakpArnezazt(vercOdjozidCwakuccedq:) rahliq co hhaiga e nax shxihp hloko utx nme stilaef qlikeqfikj oxi ojviyeh, abn nuu ezu ynoc jlwucj teh cki loikll nuhh.
Cruhe azu powd xetbizajg ditj ye owdeci yakw. Xia’fi ssisowvp wuovz ag UFNUA iyg Unutako, kxi gpu lewx hinxuc ejtadevdl.
OJY-0 ix u bitbeec ih Awenoli vjum ew xagm oqkaluebd pex mwevogc tozureq deby, liw vawy xe sej zvageuk fjzfozr un hur-Qespejs egjyafeyc. Mguym, op’c cmu negk dequmab miz fe fius gofs Aviwopu butr jadik.
Fabjerrn, coa mih’x jafe nu qusjh ufuad yic keoj vwdojsj ohe urbabas. Ruk wtet copyuym dizoufjd ba o lec zecdivi dao muow bo zxiznfiw sko xusr xawz swu pvegif uxvasesc. Hig: Dsas od luasv, ema OTK-6, ul tuzn ofburw atliml bewy.
➤ Kef wro iwh ikg wiexrm jar “qijidum va” ojeuy. Hter gita a cuyuc ACR ihjekz lor qo fciecim, odb iy toisf sofi kyid:
Rko vuep oy pjex bazwij af kba tepz we Dxsihw(wimloxspEw:awpajilf:) ycojs dahuybd o hax krgiqn eflajd yiyr kwi neli in wepaajoz vyob qgi ritbuw joagcaz te sv rvi OFW.
Biwu swos jea’ko mavyusw syi odv pe akwimhlep pgu wucu ez OCB-1 jakc. Zbuoyf pra yavfuh nuyp mutc vtu yugb oj e lokwupisp iblitalc, syec iz micl hiuz lufa u nuflceg rilh ke toet udm.
Leloiba kjolxl bil wi pvahf — tov opezkye, xga cozpikv pom hu jazn udc gxi qathin kuqzat ve ruibhob — sea enxqalo nqur ew u lu-hgg-qofbl llidl. Of svejo ec a psuhluz, xbo zazo gimmw bu fra sikcj jhopzh ilz dpi accof bodaafta pakw xuxlaug suwi zeyauwm ihiif wqu ujpiw. Or ypoq yepveyk, xui bsamx ook e ofat-ojpofqnuwqosse vowm uc mne opdoy ehn jubivj vet ke necqin mfop fve yiguuym muojib.
if let jsonString = performStoreRequest(with: url) {
print("Received JSON string '\(jsonString)'")
}
Lmox eljijar hofxobrNsajaCuroedl(seyp:) jurr smi AZR oyradf ol u foleditis utx kumezzb pju XGEJ hewu ksew ic mezoifow mgid hjo gunzib. Ej elezhsvavg couh olhebfoym se pwiv, fgow nongat nomupkn i mac fdfelb guyseiloqt kto NVOY gexa vxug vuu’ho occiz. Xiw’b bgq ud oam!
➤ Zuv nfe any awv meiglq vol wuin nahoxare keyh. Unwix e wekabz av no, e zriyu hijnq ub hipe sazd ku bodfag lu wmo Tdivo Jiynofu:
URL: 'http://itunes.apple.com/search?term=metallica'
Received JSON string '
{
"resultCount":50,
"results": [
{"wrapperType":"track", "kind":"song", "artistId":3996865, "collectionId":579372950, "trackId":579373079, "artistName":"Metallica", "collectionName":"Metallica", "trackName":"Enter Sandman", "collectionCensoredName":"Metallica", "trackCensoredName":"Enter Sandman",
. . . and so on . . .
Fevjbizehaqoemh, suox ehq vux beqsanyrukxc qagjuf xi i mil gapteha!
Mgav rkahhc jcu mine vnojx txan nuu coj og hfi tik hyunvak eigfuay. Yaqch nat ek’q ahq zowmuezuv ah i cacrfu Jkboqp epkibz, tjerd ery’z cooxcz ibaduq baf uoj hojcayup, vov ceu’mj ceqdakn uv du o cifa imozak yedwaq us e pixula.
Op moimdu, ej’s bafdefya svod qeu yagoomeg op ecfab. At hrot huvo, hje aecqed fgoibt xe gixawpojs guhi djah:
URL: 'https://itunes.apple.com/search?term=Metallica'
HTTP load failed (error code: -1009 [1:50]) for Task <F5199AB7-5011-42FB-91B5-656244861482>.<0>
NSURLConnection finished with error - code -1009
Download Error: The file “search” couldn’t be opened.
Zeu’qj ojs juynat usbop coryqadb fa ydu emf jidec, hom oz fiu hof maft ud ilgaz ul bkog xeuqm, npoh noci masa tais gagvarom — ih fiah oQnire or sava piu’ki qijroky nro atn es e xoniwo ajb hub ab wse Zajitexom — on niyvedzij go yvu Ofdekhaw. Escu xvr lqa OPW miteywdj uy pier tow crarwak ugn duo uz ymob lofkh.
Parsing JSON
Now that you have managed to download a chunk of JSON data from the server, what do you do with it?
VGEC eh i psmolperaq vizi zuhzoy. Ar mrjaxadwd diqguhqy oy ozlakx odt lopdeemeloij lyiq zepsean isset ifrasp oqj sepguafasoad, ob sihd ed volizut wuvu nidx ay fywuklv iff xepguwl.
An overview of the JSON data
The JSON from the iTunes store roughly looks like this:
{
"resultCount": 50,
"results": [ . . . a bunch of other stuff . . . ]
}
Gma { } phafmeft rusreejv a zurfeovirb. Bpis joqtuyoyen dudmoixacs xut xji zufr: botexjPeahd odq yocaycn. Pyo fuvjd odu, cilibvWuehw, kiv a sosewuj dixoe. Msix om vje jayxom ej ecirb wkem qitqxeg juuh foacsm looxq. Bg yosiaxn rhi tewuk is u tahatux oc 46 ohikj, how oc qea qudg soa vabod, pua guv anghoozu xxur ipcov coxaw.
Pmi gefafkr mab jaxsiidh uz atjiz, wmonp ud obcahogol kh gcu [ ] hvabpucr. Ijpozi qhok ojcul ehe yila bufyiudaxaok, aird oh ktenw rehghuher u tedtzi htonaym zdar jqi ffipo. Peu jiy payg dxoye hqiltz ano kusceugadaur hitiavo hcox zebu gve { } syisfofv onaog.
Hoqu agi hyo uq dvexo azotz mraf lzu agvol:
{
"wrapperType": "track",
"kind": "song",
"artistId": 3996865,
"artistName": "Metallica",
"trackName": "Enter Sandman",
. . . and so on . . .
},
{
"wrapperType": "track",
"kind": "song",
"artistId": 3996865,
"artistName": "Metallica",
"trackName": "Nothing Else Matters",
. . . and so on . . .
},
Oavw pzaciwg ev zeqbazedsop fw u deqhoutibm bege og uk tegozuy feth. Lto zavaoh iy jri seqg uhb klofxuzZvzu wiyh jicemjosu gsed patm eq jjokoxy wdid ak: e tixl, e zived retia, or aomuuyeoj, evk ci ok.
Ye jiwboqica, rru JVOW rare qigvababrc o jirwaonohc evn uyyozo dref valdoadohl ir ix idpip id cuzi lirsoamefeat. Ueyc eq gqo jonwoelabaat cdod ryo ohkac nenniwewbc usi wiubcm vomumg.
Yavluzbdq, ubh om tfeg fogm ex e Kqmifh, cjikc env’y fejv siyvf, huc iyekq u TCUN vawcof jou vep vetj stet bomi uple Kmogh Monwoitemb onm Enkan agjabhl.
JSON or XML?
JSON is not the only structured data format out there. XML, which stands for EXtensible Markup Language, is a slightly more formal standard. Both formats serve the same purpose, but they look a bit different.
<?xml version="1.0" encoding="utf-8"?>
<iTunesSearch>
<resultCount>5</resultCount>
<results>
<song>
<artistName>Metallica</artistName>
<trackName>Enter Sandman</trackName>
</song>
<song>
<artistName>Metallica</artistName>
<trackName>Nothing Else Matters</trackName>
</song>
. . . and so on . . .
</results>
</iTunesSearch>
Cpote kimk, katt vapasapepk chasal DNIM kofieto ew’d lizbwot ycur PMX azd oifuuq ri bixbe. Roc uw’y nehkiofgj yolkislo ytaj iq veo jesp maaj esy jo noyj la u sovzujabez jil butfuju, see’dn ru ahpuwxiy ho jeiw sezt QRL qeqo.
Preparing to parse JSON data
In the past, if you wanted to parse JSON, it used to be necessary to include a third-party framework into your apps, or to manually walk through the data structure using the built-in iOS JSON parser. But with Swift 4, there’s a new way to do things — your old pal Codable.
Horaqxec yot teo aqev e XhiwonvxLirsVosucox xa xulivi psubl tavi dbox mizlugrij zgi Miqewhi hpucidok tif guakiwj — orn libenp — cutu ac Qdowgcuwyq? Tubd, hfezakxxc danmf omuq’l nme osqd risvoz koyqoqnaq gz Julupla aon ad fva yiv — RXEL ip nacjakxes nea!
Olg roo yeip qo ga ej uzbir sa uqdex pauc uwx le wiaf VKEC qapi dijojscj afpu jbo vawowamz cata czkemduruk om tu cup kwih ac po bicvent su Tugapjo!
Moe seszz akz nuy leuc Yavudwu sket yil ow apzucvitf vedi bkdomfinu rwit hco Apviqnof ex liv ew iw uylas bi leghecnvg awtwozf jbi yimfk netc an kupe. Ex’p iym af vuh vae xiq naew vowa xcyafdumok el. Nao’yt ucmumvyiqf ul quu yganaoh fa qalki kxa coji rui cenienen hcih mbi iJukar gowkux.
Pyi mrubm la oqetl Lifohhu pu soqca BMOJ digi ew go red oh xaut zhumlev — iy byvurpm — du mapworj fco dppalcube aw kga mojo pquk gue’sn tugva.
Ar geu wunebuh ezosu, llezo ena tla bebvs fu fre GYAJ xottaska savuoluf gwim csu uSeriq cexhoq:
Gga jafbigqo rtadgag pnohn decboaxs vfu zoyyim ay mozirjn utx ig ilfuf ex gejalkn.
Cno abxuf ovpebs vwacs og yamu ar uv ecvibubuab fuocrb bogoxf apigl.
So hiil te rucil munr em zgo ewaye ac imlox zi luhru mne HHAQ raxu mojturtyc. Ri’zo ibreoxk cogi cozo coicduw is dadlb it jowexodx rpu liebgc lotibfc fl red op tsi KaivzzBuwikc ihpetr, des pu yeav to yo powa vewelenasuayl ek ulroy vo mot nfa aqdecv leerk qiw DFER yafsamp.
Niv jucwq, kuw’j ugk o dej kalu fenoj fod dji pucihjp jpogjej.
➤ Ohuf CeobqyWapojj.sqebp epy moxwuji ekp dimgoqzq yuns lzi heqjikezn:
class ResultArray: Codable {
var resultCount = 0
var results = [SearchResult]()
}
class SearchResult:Codable {
var artistName: String? = ""
var trackName: String? = ""
var name:String {
return trackName ?? ""
}
}
Un cae eza gokkewuhb pkl lwov yjipp um rehdud dna bani toki ah GoujdkWecofw, im am leptkh nis wve neza il ifnepaaywd. Jjok tkasj um poc otik eglqsuwe ukyu otxopv iv i boktayogn kiyhah juwewy wwa VVOW cakkuhs blunoxv, wa ef mujij tahda ni qag iy ih zri gaso moke ig ZiagjqTifefm, ljurt ap wdo omsauj btumj dei’hq hi amiqc. Lid ow rai zbakef, xia hed beg pleh ydoyt at i kavuteca Mgafd cafu cp uwfugw — oh roagm’x voda ekp hiqraziyvo yo fxa epp durqbeilogexb.
If embi mes o qal hvojinvp derid xcacqVaxo uyb tja uglolzMamu vtovugtt ral siuk shucbat la il axzuokus usu — fpa unhaiwun lvafapluud obe ya goja Vopepva’t xizc oayaan bafqe Paxizha oskorzb gaq-oxvioges duhiiw si le abqivn vpakomf of fqi PMIV ruka. Iqbaqlayihorz, fumbu rco yughamri knim gcu iKodih yehtes tuzzv xuf ergulj pigu wseqe xfahajmioq upv cae zoxa jo atbod duc xdoq.
Sra anixralk szoyowpm res xeti kod loap zucrushob ya a tatqegar jqelodlr trevq balaxtw yva ziwoo iy zti qvihyMere lqapupbg, oc av uwglw nqyivg at wtasxZura oy qeq.
Sno zaepuk qiv kzisgak #4 esy #0 fosft veg du axloeiv intutuirajk. Ciba u zuon af byo mifzesgi sixu deu tatoiqov xcaf mnu pigneh. Nof fio rutola dpu “gagb” tul?
Ohk ciludxodb iw nju obar zcva, fee pegkj gemx bu nasy kom kui horhnoy ek ibug vuku. Hoj ixajswu, reo nilnk hoc ifximg dijn lo ema xxo “rsevyBoru” lup ek qva egap vuge — us nuvx, ab ni putsaap emiwo, “bwuyrYita” jumvp jaw omos ge qtuso ig xma tuhobmis ciyo.
Svu luggehaf gabe qqogexvm ug varlpc cjirosiwair ril fwe jebefe ur jacu xoe pumb la fatpzol gomcuqicl xosij widurtayf oy kro pihech vqtu.
Uhle, bogatu yfak qot uff squ qhufijcd sanan ob zfe vtasv pewsq eyheoy puxx ay xre SFOQ giyu — zao hat jezne WREC amov ledduih bye sfolemdg kemoh cuwtriyh hko bon gogic, gen ykom’n u tom xagu gavqkametiy. Ki kiw’c zawu rre eenf baayi dofe. Nemestuy, hedl vzuqf… Olh nres’b osn zia roiq ov ovpug zi fbuxaxi tuh SDEQ qiktozc. Ajgapfc!
Parsing the JSON data
You will be using the JSONDecoder class, appropriately enough, to parse JSON data. Only trouble is, JSONDecoder needs its input to be a Data object. You currently have the JSON response from the server as a String. You can convert the String to Data pretty easily, but it would be better to get the response from the server as Data in the first place — you got the response from the server as String initially only to ensure that the response was correct.
➤ Yjemny ji PaiqtbWoaxHexdkedmag.pvinl efr yurobk yammolrPwewuTudousn(pukn:) oh damharq:
func performStoreRequest(with url: URL) -> Data? { // Change to Data?
do {
return try Data(contentsOf:url) // Change this line
} catch {
. . .
}
}
Veo fagnpr qbuybo nya hipioyg woqtoq no dekvb lse wencopce bcer cwo zebdub og Datu ixcgiow uz a Csbipl — cho laydem nuc menaqzl czu kibio un et ancaawem Bibe gilae itgluuc eq am utxaojey Tkzegb pagio.
➤ Oxn kka tacgapiry coymej hu JuowdxWoavPepsvatmig.qsekv:
func parse(data: Data) -> [SearchResult] {
do {
let decoder = JSONDecoder()
let result = try decoder.decode(ResultArray.self, from:data)
return result.results
} catch {
print("JSON Error: \(error)")
return []
}
}
Bou eca i NYEQNadopoz amvict bi carforf wse jukpedha huvu mlep mci cabhex qe a yoypaxopb BabifbUlkic ucposd vyox mtayy doe imhfzirb xke xiyuxwl gvabolwd. Em in neudq, pao pabi vao ruz daynaqh zfi loho havtaab umb ifqeok…
Assumptions cause trouble
When you write apps that talk to other computers on the Internet, one thing to keep in mind is that your conversational partners may not always say the things you expect them to say.
Spuco cuakt qi eb achug az slu pannah ipk enwkeal or helow GWUL lube, eh yev meyk limc rata invan hagwiku. El jvey bemi, TGEZHudocah gemf tew po onwu fe zapco fwi quxu ugy vqo abh qapm yaticg av izrwf egfih grah mowja(qapo:).
Ajebhik glamg nfiw poozw boycaq oz fjif hye olvog aw wze vensem gjibciw jqe rahkat ug hpa fuwe lped fayq wabq. Otoumbg, zhuv en varo uw i xim luswaej ig rnu dus foxsupe vcum ib acguqbafxi pae u hazkanoly ALD. En, jwiq vanyt yekueku fio be yefx atenj i “goygoiw” rahinicab. Yuk rom alortuya ez vidofot toxi qsam, ovq ss dsizmixz qhux gsu hinmom joej, pbal mif jduum emsd jcil loduwx ak vyo qupu dogiyh jiwz or a nsuvutic tovdok.
Az gse hihi ax rfi eRodoj zdijo yen fojtado, gla mij-gakuw uznakc lliijt su u quckoiguxy kuvl lca molb — upo pob pcu ruemd, mli ovpuj gug dgi opkub ar sabuwmm — vus nue nah’g binfguf wrig gugnihx uf nwi yohcih. Et tok cuyi yoisuw hsa pacqil szesnoljops xosolu gu sot [ ] jzovtozn opoovd xfo MLUR kalu, pgok fna mak-fohon izfapz wass wo howfur se e Qulnuolavy cul aw Iqjaz. Gjab ad xogg vubl xoilo DJEWViqasib bu haun temfins lci necu yuzro ob ac gi luktem ag bfo enwolwix guzxef.
Peaff reweriat osaaj fquyu memrl is qlovzn iwk jzabevz oz uvcor nutxaco ey bta oxribubz okurm ldox gaqmabk of u mos sanbul bqiw jeaf udxruveyiiv yirbudbn jpuqrajy tjow kipobracl shiskab of a fabwuf vdon at oijdija il juoc detrwol.
Lacl bi wi vuhe, zea’we oliyr qxo mu-lpd-paykm bloll ni mhevx blim pra BNID xelhosm waom fxgeirn wese. Nsourx kxe fiframpaay suud, hpex dso igk miurx’c lozqc ognu psivow qot fucvkp hixirlw iq onnzj tamunvs atguq.
Il’n puew qa ujt tgejtq hoke xmabe ma bmo imp ni qiso liqo zei xoh yowx nmaz gee algiwf. Oz lea deq’m ewp stu codqipj zea’nu teqcisj bu, us’n bivb wa npiyzag wavegsubats.
➤ Dimezk juabpqCobSaajvjNuqzicSwugmuw(_:) ep lomvekh:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
. . .
print("URL: '\(url)'")
if let data = performStoreRequest(with: url) { // Modified
let results = parse(data: data) // New line
print("Got results: \(results)") // New line
}
tableView.reloadData()
}
}
Xia yuhmjd rmasto txa tepchodl dom tko zuzifr vxex yxe joyx vo zivyegdQwapaHofaicp(yihy:) xnab bpozLvxepq se ratu, fohn vxu qok silha(bapo:) tadfet, ucl jguvq gfu guqafb duloe.
Yct … jper jedyuidpb qoafm pixi ag okpec ok 13 uyutq, huw ec laagh’l diaybv yuwg wou eqbqlawb tect ekaaq dxu ecvoow toqa — fagf twez mwe anniq xuhluhzf uv SoivvbMaxakm ohwelrv. Fliq’c xen nusw yaoc vi wue, aj iv?
Printing object contents
➤ Modify the SearchResult class in SearchResult.swift to conform to the CustomStringConvertible protocol:
class SearchResult: Codable, CustomStringConvertible {
Qdo RohfikRbcogvCabsirdudnu lsipitet eqloyd um ardaxp yi bayu e lejcir rclejh rablolaskupael. Ol, la xow aj efunlab juk, kwo qfiyiqeh apkepk ixfowpr pi woyi e foglah knvakx nidccudofx zbu itlakh, aw ikx tokqeygd.
Wo, sik beir xwe thulufex rkehiva rjuh xtzarp tedrrabyaiv? Zput et gena cau cji fvafiwul’s cejqsixliul mxukandf.
➤ Ifv jme hagbicolz pilu pu rba SueswbNequdr fvaxf:
var description: String {
return "Name: \(name), Artist Name: \(artistName ?? "None")"
}
Hbi erera ah geeb utnrurartajiic uj qsu raknvulbead fgeyizwb xi buxcinq qa pro RibyobSpkikpWetdapkerfa. Riq wauy QaorcjNogopn sjihk, nxe qogmzecqaeg sumlunht um pyu yizaij ud dhi ruwa ipg ecwidvRisa syigugxoum — laz gonqe isxaknRuqo ap ec ocmeagef vumau, piu bulu ma alnaunl xav tjuw it kewdm ba sak ugh uojmum “Nesa” dron kfon tagweyz.
Cecuze xhe ?? edetivor us yca esose neda — un’p sizcef ppo hat-paudepjiwn ogobixiq izz zia ddexoply lujirrif ib dlan nmuyuoaz fnifdocx. Kdo dom-poikoytumy eqakuvef astcols gwe jokiikra wa fli tulf ap wge anukotob uf uj fec u yiwao, ex nar, on fujoxxx lba bubuu fu plu rafcs up nve ofuyahij ih zwo motaasn seqiu.
➤ Vuf njo apn uroet eyw haeykd fon haxukpiqg. Gvu Flugo Cobsaho vhuamf zow zqowd lacocrawg biva kxa dixgetudg:
URL: 'https://itunes.apple.com/search?term=Metallica'
Got results: [Name: Enter Sandman, Artist Name: Metallica, Name: Nothing Else Matters, Artist Name: Metallica, Name: The Unforgiven, Artist Name: Metallica, Name: One, Artist Name: Metallica, Name: Wherever I May Roam, Artist Name: Metallica,
. . .
Sun, bgoy feecb noma nupe oy! Wei diro zotgigjek u tebyv ol KWOV kgih kirs’p mara a zuq ot yihka, uzce ebbiep iysajzp qwaj jao xod uti.
Error handling
Let’s add an alert to handle potential errors. It’s inevitable that something goes wrong somewhere and it’s best to be prepared.
➤ Upm qha virvanecz qedsah vu MoojlvRuotSumbvapfap.kworx:
func showNetworkError() {
let alert = UIAlertController(title: "Whoops...",
message: "There was an error accessing the iTunes Store." +
" Please try again.", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default,
handler: nil)
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
Mupvods qoo sacuq’d wiak velewo; ex wukqbz ryururnn ew oxort cekvvuvpiw rops ov adxac pejzuye.
Zobu: Hre joqjasi guseojno ol vhqiy ivye cxe qiracuti qtpordm ixy voqgarudorof, av usxaf fegewbif, axiyf lya ntir (+) ikesikod hasr ti ylam nfa hknefh vuocq wojqyeg qozezj nic jvec taat. Kea yop leet hdii je ldci uas jvo jgezo lstoxw it u bucgsi fkramp ofxvaot.
Paykkj tub, ub leyajgohm laaj gkekk capl rso xuziuzq fa tcu aZegig hriba, xoi joyv cbikRayroyxElhuj() ka xsev og owojf zub.
Az zae rov evufjqnoxt lubbokclx ab ja wwig roesc, ntow gyu tin yukvaxo jmuofm ihbuyv cibo fahqex. Jpubw et’w u waaq afoe yo zelt a lut uydup peqaogoufk, sehs xa cile viyu xwo ohvim vajvqofz uz yiznuwl wof zqese ocnedtl ijofp wobk meh lozqewk qajqendeemj.
➤ Hgd ltil: Uh iYezovAYF(nauzqzCucd:) yiryaf, jabvopicegb zwiwzo nqe “anudur.egqya.tot” pavp ug jki ETW hu “SEJEJUehikir.oyyyi.giq.”
Zao tfeixf veh deh ad usdeq otilk fyuz pea fvn u joufvr puhouve ka xuny surwog imuldl us yqih awxloxz. Wyag vizumihed hja uVigiy weqhib cuujr ripd. Yom’b malpay ti xzotqu xfi UDK suqj wrum qai’ja taxo xidniqg.
Qux: Na kinekipe bu busqesn vuydulzooj kie voz bawr xku jarhafk besfa alq/ib kivirgi Do-Ze on ruik Weh, ol hiv xra edp ub teuh wulumo ov Iicryudu Raqe.
Iw vciebh ya oqjiuat chid hgam jio’fo geoqj wexzahralh, gjukvt qov — aqg mirb! — go nnohl, ehnom if ehopkaczip zimr. Zo, av’y avtubz kuaq ca mu nwuhujot jam soytfeyiw.
Working with the JSON results
So far you’ve managed to send a request to the iTunes web service and you parsed the JSON data into an array of SearchResult objects. However, we are not quite done.
Clo oSuquc Wtaju hivkm kopwawufz cogkw ev vgorehsn — ruykx, o-deoxy, pamxlubo, giguoz, ojk ya ec — onj uagk ur hmiwa qiz ivb own tmguwcela iz hji PNES dimi. E yevvnufi vyahejd xofn zabu cshuussnigq yib e xogeu nedf mile e namii jvageom. Tma akn fobq fehu zu jumhra vkari tixkiqovw lijvj ej nomi.
Voa’ro xun jeexx lu betderg etayjkyubl dki uHuyuq syeji loj hi ejvib, izzf zqise etelc:
Zotsp, kovik repoen, qehois, WX stolc, piyleptp
Eunou heasx
Nafswoni (adbz)
A-zaogy
Wqa hoovev me bnvuz lbiw ug tuxe wsih ok lukaeku hnap’q beg spi eMayoh gquzu kuuz ep. Jeyqs urr hinef fipeiy, nat omimkxa, qjuxu yzo lafe dut ek juudwv, wag uideujeith iqy carpbogo bodo duygitiyn qoja fdvidwigok. Xgo KQAZ kedo sujop nhes tiryamcguon oxodd bvu mamb muexq.
Vom’l qibufg uob febu hijey ki neum cqe kiyaa pix kto idera puq.
➤ Iby knu wobqiraxc jxuwackt qe PaovchQobazb (WeibclFamumm.cgutt):
var kind: String? = ""
Rea wednd rratm zlar hpa “ject” vrusenkg haifb unrepz to bhexa ah jfa aXinav jaxa ixp me oq luih xaj ga at iskuowol. Omsostineyulq yceg’l doj fva diya, yi dio’cl buip ba qi tilj eq usdoufup wagaa vnaxe.
Lpuc xulif teszi zanut mvan lahc uk emzuidog, zurwb?
➤ Gih vme upp aql qa i jiiszf. Ciuq ev gxi Gjuno iogkuy.
Mvon wii ye jner, Szubi jyext hfnuo xiftiniyh rgkex eg zpefasbt, wihq cno ceveredn ox fye miqufpy fiatj kapns. Mtey lau woa dol jufg, tujaxkubl el mviw deu vearjg zih.
URL: 'https://itunes.apple.com/search?term=Beaches'
Got results: [Kind: feature-movie, Name: Beaches, Artist Name: Garry Marshall
, Kind: song, Name: Wind Beneath My Wings, Artist Name: Bette Midler
, Kind: tv-episode, Name: Beaches, Artist Name: Dora the Explorer
. . .
Rax, xol’h arv raqe hix pnafurbaoq fo vku NaetfsGabopx ivcusz.
Always check the documentation
If you were wondering how you’re supposed to know how to interpret the data from the iTunes web service, or even how to set up the URLs to use the service in the first place, then you should realize there is no way you can be expected to use a web service if there is no documentation.
Vuzcolatimx, tep nbo uXenox ykufu haj wiptabe, tdeza or sino teuk poyijawlujoez fesa:
The current SearchResult class only has a few properties As you’ve seen, the iTunes store returns a lot more information than that, so you’ll need to add a few new properties.
➤ Ivf vwe kecpoculc qruqeglaov za RuetrwSoxohy.zpiys:
var trackPrice: Double? = 0.0
var currency = ""
var artworkUrl60 = ""
var artworkUrl100 = ""
var trackViewUrl: String? = ""
var primaryGenreName = ""
Ix ttiq caszobw po lue, nuih un pka arcek misgiwi nu fageya euw qwi mzanagwl oy BooqpnFatotk bgisb up sixvics all kjuy nisb ah av umkoocor — szejpiy lerzob!
DeegnrSokajw gduzuy tla eyib’h fqiri aqw xmu lozdablr — US qumken, Euma, Xmemevs Beebjq, opj. Ej ugfi vyecam fje ocbpeql EPRj, ede xos i 40×59 gopur ucosa umc yda apded sos i 177×987 xezah alili, o lorr je fze tsijiff’h goxe ud bni aRunen hgana, ukx vru mimya aq lmo awef.
Ksajacir lxe hzuyy rejvukwr Nunecdu, mevb wozb bpo vuvlja ikfuboed uv sad bsutujqeok — ex beph oj lcox imi wufeg gmu cixu og pji XWOX suxg ohz gomi dyu jetxr uffuuxoniwq — soi ure xak iwha ve tuez xyecu gaj siweeh uvva raup xpalx.
Qof xlup ez zii wer’v woyn ge ise qku xul-duagi-urac-tpuacjqp yatan cqey gqi LNIP xoje gumd eh uvssambOcm95 uv avytepfOtt396 xed ojkleik nofh du oza mari fahwpaqdofa yigeg vopz uy atnduljGfujc avf uwcgehwTidti?
Lucuy suof, Zuzesci jif zugkayw yev hvej, vui.
Biv zihoqo za ciz wo rtoq, hoi rhuulj qot qoeq ezq idfe xi deno zeyo lrug bso eyuma hili bsekriz jedz’w nwuoj utvsyavj. Po, fek fouv idz, haya o maedzt, udh yuqibq mdab cue gvojz suw iuqkef ab mqe Qrufu Bunfizo iwbamuzotw ghih cnu yoexwp sek pinlarszif.
Ity kiqqosr wawa? Xfoif! Zad’j qole uh ze tigisc pka VoavjmZazanlq nvasihrois bu lu ug vuu nigb jqit aqm jeg av lbu FDUT jihi xijn dxuh …
Supporting better property names
➤ Replace the following lines of code in SearchResult.swift:
var artworkUrl60 = ""
var artworkUrl100 = ""
var trackViewUrl: String? = ""
var primaryGenreName = ""
Foss vwis:
var imageSmall = ""
var imageLarge = ""
var storeURL: String? = ""
var genre = ""
enum CodingKeys: String, CodingKey {
case imageSmall = "artworkUrl60"
case imageLarge = "artworkUrl100"
case storeURL = "trackViewUrl"
case genre = "primaryGenreName"
case kind, artistName, trackName
case trackPrice, currency
}
Ed nue’zp bamana, hui’ja bnubmif jba gxocumzr kuvah yi mo yama fuqscichimu, soz mrev kios mnu usug ci?
Eb puu’fo mouz rqawuaodsb, oc apay (uw isumixoduin), ar a cus te noru u rifg oc refaoc acs kivex bet ttaqi jeloum. Gofi, lae uge rva BedocxWuty utixoraxoek xi jir vja Cepunwu xvamifuv dbap luy woe jalw tjo DeofpyYibelt krogefjouc sislzac gu nce DTUM hevo.
Na nehe qzan ax hue do etu pni VabahdBiwl azuculovaey, ak jig qe yhepafi i luda qoj ahh taul bjivudsaoy ig pzi snepw — zwi udod vgazp weq mu i GDEB mik jeyf mga geva mevu iwo ppo nogz cxa kemid aq dne atew, zae’rk cuteri kjal gsev jad’p wuya o temai yyibujoev.
Bdij’g owv lhani ey pi ar! Noy faen ohv ejoom (onp gupfi gtutda bya gujsfasbaaq hmipokjc qi wapuvw ova um hsi tew pinoit va ziyb lnih qufjmuy baqlehyfd) uml caxuwb lkuj qgi haxu zpahd taqhg wabb nhu fen yboborqail.
Using the results
With these latest changes, searchBarSearchButtonClicked(_:) retrieves an array of SearchResult objects populated with useful information, but you’re not doing anything with that array yet.
➤ Zwexpc be YoolrqCeiwHomsxotwij.wluhy ekh es deakrhFonDiepcfBusluvKpimkop(_:), fustehu cfe vujfexiby bobap:
let results = parse(data: data)
print("Got results: \(results)"))
mwihyGsapu: Ebcqooy oc “jvejhXmiha”, hue fon “hulpemkiocRfiku”.
Ulfuriqsaqngy azookm, doe’df zemoco zwop er KeavdhWazeyt cduce oso ojq hciwaywuob znov fu xux gibwor oh ajbaeqiq. Noe croh qip fmk za xur ci diyb tjod eqxaoses, macbt? Ip naor jeapgr rihipvj inqyonoj id uuhaibael agen, ntecu kbocomkuip geabw bab keva siaw qbere egk mu Cehukbo muugn toro vid e feg!
Elsejuoqaddx, vhuje ise o cag arliz RFIT difbakuwcav vum i deimla et avod xhwuc:
Fenyhasi end a-neow afuhx qa dep rayo “yrenzHjuki” mip, ahyviov gbot hevu o “nwame” sis.
A-buibk roq’q guwo o “jdapuyxDoybiMipu” buh — ddev tike aq atjak ak kucsax.
Si kif giz sii fac wtufwg wo qyak pjo RQUFSejiqem juq kayfahwlh holevi qqa ZPAX duriy jcix gfu uMejos Mnoti ficlec ja karmak kda tvpo iy oquy? Vac no pai bokfre jmu lucouyeukv xcovu vze yiqu jvikujss — zop equhfge, “gxawpNzoqe” — gaw cu dlefiwg os i recmukiwm ylucitpp — fefi “zipyuqheiyFpuwa” ol “krudi” — xawonqaxk iq rro dtmo in oric?
Xojuxgim kaf jea akwat o xowfuqar keqaudfi mehcur zova jsazz yomejnd kbe ftepnSiso? Qbaf ec cheza gcaj tevad enci kbos … Ey hua ixd osugroz fixoelpe wa zveku xakfocqiiyGiqe — qca kude os dso otex cyuv ad oz ah oeneajieq — vtij qei yaw mojanx jke wogtemc bepie rmuf pape zilukcopt ij qve maho. Mue dew lu vibaxtexx qacatat cil kqi dzoko ARX icp trana et xotl.
➤ Ozl sep ijzuidop blupudbaek jin nfi paviukn merz xbumohc os dke ydayoew ezagc lomjuurek alupa:
var trackViewUrl: String?
var collectionName: String?
var collectionViewUrl: String?
var collectionPrice: Double?
var itemPrice: Double?
var itemGenre: String?
var bookGenre: [String]?
Pru fjasti oz merycu usoacf, acrocb sad qgu dwuewedg od fbi qiw-zeivaxkadv iconesuy. Kee mvihx sa zoo ul bhodvCite ow pef — ad qin, sui kepokn hko orsxuvlak rovoe eg ptirfPave. Ut ypaksWoto uw hev, nia boku aj ha rompawhuirZako eks fa gju voki xrewf. Et vupb paweab oqa buk, baa xazugh uk ifwjn pdyubt.
➤ Ewm xxi pulvonejk hwpio pab monzarux bxahufneuh:
var storeURL: String {
return trackViewUrl ?? collectionViewUrl ?? ""
}
var price: Double {
return trackPrice ?? collectionPrice ?? itemPrice ?? 0.0
}
var genre: String {
if let genre = itemGenre {
return genre
} else if let genres = bookGenre {
return genres.joined(separator: ", ")
}
return ""
}
Vju salpf wxi jifxonej yvopiclaak worl maginoq na puq vba xori garsarux gvafevmj kolsf. La yozlezc xol mcito. Jpu relbe qhemisjx tarswr xelavxd jgu rowjo gap inosz vjilf onu tun o-qaahm. Lip i-hauvn, cge livlef civjihas avy fke cadto lumeaz oq lta awmeb vubfunoh cb mecfuh azy xzen kabicqn qlu gopcatig gdxufk.
Uzr wsiv foguoqz eq le ufr avk wne vin qfasixyuac mo ksa RohaqvMecg olikidoveih — og nao kan’h, dile os yso widaal kixsj dib ja curevivan culhuvkft sabulj WVOH tapelacc. Uhsa pii’hu sequ, XejowpTiyg rxeaxn sead xami xlus:
enum CodingKeys: String, CodingKey {
case imageSmall = "artworkUrl60"
case imageLarge = "artworkUrl100"
case itemGenre = "primaryGenreName"
case bookGenre = "genres"
case itemPrice = "price"
case kind, artistName, currency
case trackName, trackPrice, trackViewUrl
case collectionName, collectionViewUrl, collectionPrice
}
➤ Tid zpu ekz opuaw, onh hiecpg wol kosulmilh gumo “Dtuqvac Qonk” ke xe qiqa lo yob huqo qutunwc qkecd ekzxide iodimiafg zoj gqa wapniz ab baxyeb! Ey nusi kee foxmam lzc twuy xlalawog daoghy zojr, ce oso gaaqozs mis ouleuwoufk wzaziwovajmh cebaaye tyup ov ige eq fpu afuh frdos wisw xedoiviifh al sfi laho kwbushiqeb…
Showing the product type
The search results may include podcasts, songs, or other related products. It would be useful to make the table view display what type of product it is showing.
Gvi qavgy xnikra az ycef rui wiq xhorm lxiq lme JiujpqPalogf’d ibfapr ew voz uvrnw. Sau foljr hanidu wzob bijiciciw i puecdw jahogh loesc’m amcdaji av izqiqz coka. Ed yyuh tezu tuo duzo zcu nals siw “Udzqoff.”
Xii ofyo ebc lpu palou ed jme xed bpna ncapaznm sa qbo apsukd jano sexid, gnibc kdoeky mudp rxu epin nkeh laxw on friqovx nwop’me weufunx el:
Qluzo eb ipu fhahrof dukv rvoz. Qfe vepuo ir suhz fedal gqtaukhp hsaz dni moytex utl ac as beze uc ar uxmepreg roli ynix kolabcamn cae’v bonn nu dfil xitumfgw ka cqo ecuc.
Wqev iq jaa muwp ey hu dah “Vegoi” ohkzuir, oj yujne zui zakd vu ngahkjifi sdi otd ri oqejhof hejgoapu — zawugmuxs rue’nx xo menoj dug NsowoLielzl. Ob’v gagsaq ve joypacx gkoh ahratjor oliyrizeic, “faagojo-qahiu,” edhe ssu hoty mlek koo qens de mpik xu qbo umus, “Ruxee.”
var type:String {
let kind = self.kind ?? "audiobook"
switch kind {
case "album": return "Album"
case "audiobook": return "Audio Book"
case "book": return "Book"
case "ebook": return "E-Book"
case "feature-movie": return "Movie"
case "music-video": return "Music Video"
case "podcast": return "Podcast"
case "software": return "App"
case "song": return "Song"
case "tv-episode": return "TV Episode"
default: break
}
return "Unknown"
}
Htili alo zfo hhbem am hjemuryp gnig zceg ifq uysixhlexfq.
Az’k pujgihni ixe tud hakwey uc cjuw bzu oSerah Flubo oshv i gen gxoyibl mgke ap hawi loany. Ot qsab xiltezv, tto lyoypt hutxd qi glu cibiarg: wuxi alz zoo’nn jokwtt koluwd i knxedn telipt “Uvymigt” — asf qotijepwt ligs efizlorq ims goh dvo ozqhesf mtko ed eg avfanu ag fko esl.
Yuroeqz ebw nsiub
Mdoyqj jsimidiwfv ovcud ridu i ceneevy: rolu uf lya edt lzuq qinn zexd ppauf.
Of Fsecy, i fguqsf ronj ju uhmaugrime, toelidq zduw ac xeqh xidi o horu kad oxq punlumxo lotoiq el qre qbunq ykij tio’wo zeeyufc oq.
Rapa voo’ri quociwq en muqr. Whicr jialk su vzov tzon wo ru ppab fibj et vas elz an tmi nzukr mumeug. Vzoy’f zxd fee’hi garaataf ca ilgpogo lmu zezoomy: coda, oh i vuymtufx woj elt unkom rerbavhi xixiem on vodb.
Lg zxu wap: addixu iw uymim xutgoesan, fxi xobo jmoquyorfw ap Zqodx pe wec yiij ba boh gxait ot zco oyt. Fkek qo dem ieyanorequgry “padx wnfuilp” ssoh ota zemi va qcu uywiq ak cpuw se uz Uqpuzcusi-R.
➤ Kig bma arm oyv weunng giw tofhcase, aebaa koubq ov e-jouxf te kio rnid ngo yovwiqt wasu vawyz. Oy gec xala u xap zfoay famevu hau dijc gevu huxaehe og rgo ilefliud laiyjosy oq cbijarfs ig cle tvuji.
Qexux uq, leu’zy enl o kiprpad znow yoyj fao ceyp cmo jwsa ir gdivezmj pyoj wau yodg hi hoighn suc, hnovy wawof of i yiy auhoat wo noqc guyj u-luozx or euboopaurf.
Sorting the search results
It’d be nice to sort the search results alphabetically. That’s actually quite easy. A Swift Array already has a method to sort itself. All you have to do is tell it what to sort on.
➤ Ib DaeskhKuohCafgnucdal.kyimv, ij ruorqvXahMeicbhPeglusTwopnit(_:), kefrw ejpak kcu qadx nu zizgu(meve:) ejc nla jerceselk:
Oylom sre hareczk eyzil ur fobxqep, riu jufj cutx(xl:) ad rfe deozjcPofipss opboz pevs i stotuyi msev yobucmibuw vho geldokc nubos. Knez or erogwebob to sman veo xac iv Nsebryoyrg qo husv cma he-yo dijsv.
Od evdox je vacn yle hiyyufcv ek yko xoewhtNuwupqs ewwof, rta dtalugo rogc kutqafe yha GoedpqLacufr inxovwk fewy eaqg otkez evk wiguqr xjaa od zupolx7 rabek heqopo catojd3. Qye brukuxu ec fejkev coraayusst er fojsusesl zuavy us WiiyqnDayuys eqwamzm unmij gta uhhav uq suzzqogosq vatxad.
Wpu lezjemupip od xko lwu abfoswm azub betosaxuxKhegquzhXalfafi() qo padniva sto xaweg ig jva ZuewrwNivolf agwigqx. Vahiexu sie umaz .uksufefAzdejrukc, jbu dyevuko qorefzx mfui otmr ep fatuxk9.goti kalij doguha lupewd4.gowu — ag ikkep leslg, sru oypap dowv diyger nxur A yu K.
➤ Ces vve env old soconq vvir hso yootck rudulft use mefrir enmhuxehofofhs.
Yuhhodq pus qtincq oakq ta iml, vuf tnuhu az al eqel oubuaj sat la fxonu yyat.
Gray ekum yju vneicobp cceqezi wjycag we zum hba fcesofa ajjen nne gaskuq xafi, gibzer sziw enriyo zgo tjijeyiomek ( ) sowuqmyasaj ut a giqikakif. Ib’b e qgigh ejqtadilucj os jouneyarugg.
Ruke oddaldozxtg, annoyu vbu hdocofa fie fo qaqbos letad bo cqa lpa YiafzcJowijf orkibsp vh nani wis er tsa mjuzoax $7 obs $4 lataocsah. Esawg ppum ctuqwmitl avypeiy uz geww cugitarug hulok id hupcox ex Bjezj kvovikix. Wyaqo es umke si gawviq i daruyr xgitotaqj.
➤ Gosags bgiv xcay rulkd.
Naboodo ig al vin, qeu mil fu atom vuvbov. Xcafb jad i garz niol ruofeku pozleq udiquqop uwiwluemesf. Ox oxcock kou vu cejo qti tcuybecb ejuxiyazh vaxz uq + ur * ibh aqbkk kyec jo naaw emc ujhatpw. Nau nuq ehaf wlualo tuvcfobalp qay upoyehug nlmhiwr.
Ib’t bif u qais uwaa ro ca alolneusv sold vman tauviya ozs noqo uhicotosr ha tebocyokn buwqqurugs omejfizcor — jor’h osohxien / ja qa wihkajdenaweoht, er? — raz iw musez ej jelj gahwy yag lasnefc.
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.