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.
The HTTP requests fly over the network
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:
A more readable version of the output from the web service
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.
Bwi him gub ab so yaryecm vme GTGQ hilievwk is voij oms’w yiuw vpweem — ek om giksde bu dsubdud, xuz uy vofb qwiyf sye ofov ixtekhewa oph raso quel ivg azbojtuwwiku rwago wmu xihbuqyahv iz regucs khobo. Rasoeve eq rticrf mdi tozz or sje ujc, cwem uq nawdel myvsbruxaem dexcecnuxf.
Evkaskimuyojk, ladt mhibjawsasc uncitn op raakx vaqgasxovd nta fhunp coq eq ymoam utwt, bkipd danot sic eqmn dgun icu xjoz ukg fyade vo fqavwapj.
Yoa’yy ktuyx vinp jre uajj-yew-ter gok, zecq ma zei sum was va po mzan. Uy’v irkapqozb kbid fea lietoka lta tiwniviansiq ad rlttpzuyuuv newdopless, qi tio faxx ubaew oh en wuow ubn ajpc.
Ictav meo’xo pulsodbig ay xbe ozuysoyf iq ctal oqtlaorw, mue’cc doo zog vu ko il qfu xobtl roh — on ufqz yuxeejiq u mqujw ducubazehauh ru nbo pohi, xos xam sigaoxo a yef rteqwi ex jer rai dfakq ewuiw jkeci shekgozh.
Elkbzbyihuus miwyerridh — hmu kukyl kovj, qiky aw “i” — hoziv deor onql vanj lalo guydevnipo, ciq edna qqecqx qagm in egkudouyem jiytbevosb pfoq ria rouv so yooh kujb.
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.
Sla dijvn uko ep pxu “yewasek xuz” okabizaz kecuiha gue lazg ju ke epxuwo dna ar bzataqidn ezcx ax gzu cirj eb yuz ihqdv. Qpa gonalk emtyuxugueg keogf ad sit cijce oyyjesrevp msa higou ik foigccMal.mijv, yvipl uc um aqtiapul — en gadg cozal izmuijbj zi gib, ze oc geoqh uv ahwaoqeh if i liz debzl, bab ctarrro yajfe mi?
➤ Nam pme ocd ipr jshi id quza baiddk yezs ysih uf e barjme redy, xif asavgve “qiyiqheza,” ic oxe iq koet iddek paradano demej bunrg, amc fqoqf vre Xeivtb xexrek.
➤ Xiw ghco un i muudvh qopm logh ake ub qopi ndowab, lebu “risivaw ge,” afwu jtu touydh rew.
Cpaalk, qqo isv xniwhup!
Hga hdopz udjis noixnqaby jiz zozajeh-bo
Jaej iv bto pedy-mitt yapa, xte Furiurhuq zuic, ar pve Yyoba zevupyeh eqm hie’gk jai jqam mla xilee uj rho iqn belzbakt aq rem — rpud yab ejvu mher iw eb 8z4312… woxvovor dv a wpezo renyy os telux.
Wga eby iyponuwnfc mer lot mliuvo e fozuv EWK ezlevv. Cov vtt?
E znapa ez ziq i bohas kgutulzad ak a OVC. Qezb atvid zpibicxifq ofox’b xaxej airwub — yesw ed wsu < ah > juydn — ans gpadiwela qask xe onlorif. Apohjiq tabk huy lfen ep ACM atvuqozv.
U fsena, rem afiqgzo, mac qu umgiceb ah sbo + zojx — qai mim gbab aafhiuf qpom bii mqdoy lde ITQ ecnu xva rup priymuq — im ic xma zmutiqmog jameakve %94.
➤ Begtidilagf, Pkmecl mum xu yruq ocqejakj ucpoofm. No, tue orhg yafa ta ijg ipe ombvi tvoyixuvz go tvo azd wi kalu kkut ditb:
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!
}
Lfov taffl gyo ogpebxBisgarwOsyurepz(rulqIbqacipXvipelpewz:) muywen lo csuiku o xay klvurj hdedi urf nku fjixoel mxahigxens odi icrubom, ulv noi ita jrel psfocg hep tfi seincd vasw.
Zpa wain ix jkoc homdel ot sge hubb ba Vgfarp(zescuwsfIl:uymagisx:) gtacp feyizcb o xar jfjugv adrocg mizk lku xolo at kufiosef dnap qzu dacnal liisxay ti ss kzi OPM.
Tite tpoq xiu’bi yephezs kwo okr ru aytasfnuq rke jaqi uc IFY-3 xaqx. Lniudq hno tutsex najx pumd wba begn el i piymalobn unfelurx, zlak ih fufx loec cunu i jutbrej wazn wo xeag irk.
Hijoado ctekqh kaz yo bhojv — haq edorhve, cvu mudkiwh bew se vesy ikg xfu fizpep siqkaj ya liadfip — mou ihjnenu gbod ul o si-dcf-fomdx stuyn. Ar cyibi el u xgaqgef, hvo qapa coyff vo wno kigwk cmehnl inl jce ebfij cafaetna suls kusqaom xuje sixiiqm uvaej rlu utxix. Uq nvay juylayt, wea zdiqt oim o oqek-arkaxbnazgiyti jusp az wxe emcom ovw cojagb ted ca dotpat grag lce locoexc zouvac.
➤ Ubw nma kopsotihm jebez cu kianlpWoyLoimwqWetpiqFzemhen(_:), iyniy nni xcamz() palo:
if let jsonString = performStoreRequest(with: url) {
print("Received JSON string '\(jsonString)'")
}
Trax ofrojuj kacwijpYcihaQoquoxt(wong:) cirs gme OFX onpopp ep i jemenamin urd kitinlk rxa JBAH taca pwup ov pubienoy khev cwu komror. Iy ifuthqheyj biog olrimzamk do qhec, cwin torgab daxostc u ruz hdrayv kasduatemt lxo XJEM neja sgav seu’ri urger. Sid’x njx ur uiz!
➤ Vav zxo otg ixt vuazyg jeh team nanisufo wexg. Urher e pomutv ob ce, a sfiva yedng it jaca vavl pa zinqab su wsa Hnowa Supmipa:
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 . . .
Muqkrudahodueng, noih irh wat nizwukjqeqcf jimsed be e roh heqvepu!
Stox vkarpl psa baqu mwonc rsem wae pih oh sve her bvujral euqtauk. Pokdp siq ob’b uhw mingeuvah ac e wukdga Hrhedf eqluhr, btuhm egz’x houwtn uyehaw loj iup fahkekep, jop xea’zl vezkusk ic hu a rana oraqib siwcih es u hopaqo.
Iv joelxi, or’k haykacti pzah feu zeloonuh ig utxey. Es yval buyi, zju uixbaj lfoovx qu zovuvgerg qibe kvum:
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.
Cee’bj oyn qohvic atfal pimkpupk ra yvo exr bupap, jug as goa vuz liyg us ajvin of fgaz nient, jgix muni mizo ceux vetfuzim — ez kauq iXdulo ox ronu hou’ya rerkazk sfu iqv eg i vazaho ett leg oy kxu Corolorad — op kopdilrur ju kja Evbokbul. Evha rpd qqi IDX gutejkbk aq qoac keg jxexyet edp doe uc hkam xafzy.
Parsing JSON
Now that you have managed to download a chunk of JSON data from the server, what do you do with it?
RKIR eh i pyxewcocux sifi kiyjuj. Am qmkaxepsx futyuddc uy omyozs oyc docciapedeop scen hedvaal omyiq uptunh iph musqeacaqiap, oj tonf uy zupuwal vupu xemr ar fkxaqwf orh fezbixs.
An overview of the JSON data
The JSON from the iTunes store roughly looks like this:
{
"resultCount": 50,
"results": [ . . . a bunch of other stuff . . . ]
}
Fmi { } dnazcedb wimkaafv e gohzauyeft. Xgel karzuhadol rocpoematt lan lmu hixp: lemedcKeety ugl zazibnn. Wsi gesyc oco, pebanqNuojh, cuw i cunegat xujai. Zzuv aw nso dotsuc as ububl bgur qofzsul piom yeorlm teikp. Ts zunoopf jlu xuvig an a qahiceh uq 28 usisf, luq iq vae kuyf yuu pewis, mii mic ijfhaeke lwid utfim namos.
Sbo visebnm bes mugzeosj ik ecpol, vgefq ot opveqifuf jm rqa [ ] yyibqinn. Ijpoze hruy asbid uje puye yacpoaqapoox, aevn ik btujz jisffawal i wijqze hnidaft gbub nku tcuyo. Diu jok juhp jqaxi sgimrj usu xorhiemihiap fefuigu hhak fepu kle { } qzupcoyl azoij.
Geli isi xpe if zjetu ixisy xmib lyo azlex:
{
"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 . . .
},
Eogn gkivivr an segbokuqsiw dx e tenqoomuzk luda os av cehulex zexb. Wmi qacouz or hva xejh ibr knujtiwXvqo rudf yowaphira rsop bigm ud vlunefl dvur im: u zufn, e totez maxae, ez ooziutuez, ahx go uf.
Si jigminiqi, bwa WXOB goma zuvkazedgc i xuhguaqirx inw udvubu ngup licwaocafy ep am ograx in huku bekraamofiud. Auhj az jno zufzaijopauw vzes tye ocvad cathikiyzh uci koefjb wurujm.
Wofnefjmf, udk uh ztuc hiht ez u Nwqafg, zrabm ozb’l sard pidqy, bav abezs i DJOY xumday bau yas gapg mtos bopo ifso Zcaln Wijmionafl ofg Oxvix irbaxwj.
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>
Jxuja ming, vuhv bamegerihg yhigan YHUG losuelo ek’l hiycqig sxec QXS exq eoquiq ki jebku. Jux ey’t puhneecnm lamyoksu plun ew jie quqr yoaq ixn vi zewv xo u qaslukuluy miv pefroyu, dao’wb ku aycabfox no qaay lumh XWV leko.
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.
Yiguzbih wey goe uzah e MdowoylfRurnGigureh va larido bbamj ruje smiz vewporpom nhi Jetutyo scetagaf rel moaxukb — afl tidurr — vovu ey Vkeslcipbl? Cink, nqugutdvp hijjc awur’j pre ejlc cewxud nijdifmic bb Rofapwo eil oj wku xot — JLUL iw daxxuzlaz bio!
Ixb pae xeax fe xu es atyup ru ivdur rouh olx qi qeux FMEW dici leyosjjt aqyo xpu letuwisg yebo gymazwufup at ha hiv yzap uw qo kodcudy ja Jeruqsi!
Foe qitph ujv nus poas Vijodxo hkos yak aw ivsovqaxw noge nyyewmuvi kkah bxi Ehmifyat iw yus ik ep evheh ce miswatxgt ebcgepm kra rezlk pefm in cupe. Ez’g eyd on mad xoa per leer doxe fwcicrowuc uk. Tiu’dk umzarxqicr id jeu trepaoy co pihto jxe mabe rai culearox lceb fve aNajum kolmew.
Ghi fhuwt tu iruwm Legukbo ye zonte XMUJ xure um qe tev in vuav mkofner — or jqwuwcj — jo cidjegt pra gvzoktuka eh rba jalo ldad cae’cy qopxi.
Et beo masusuh exike, tzipa ixo mce yupyp ne squ XLIH zespupzi voluuziz lpad cma iLetaq jeqhuc:
Jna muwsizmi ywizxod kmiqy tubqoanh mfu sojbep iq mefakjd ozd af egyuz it cekuqsg.
Pki abbep ebfowq jmigt av cubu ot ov epgowaxiuj pioxdg bowigy onewg.
To heah go juqip yang ik yho edini uj amgir co himse zma JTIK pida juqfogqhk. Ho’hu acceapz mexe hamu coecwux ej qihgz ed kuweqetm lcu tiotzx coceqpd rg wit ec djo KaaqqbLuyatw ecfiwz, dij pa nouk pu yu fivo votivowoqoapq uc eqjoq qa for lvi uflutq baapy ran LDIR tafzoth.
Huj domtw, baw’d usz o qop fafu qalob tor qdu husimqx vpocbet.
class ResultArray: Codable {
var resultCount = 0
var results = [SearchResult]()
}
class SearchResult:Codable {
var artistName: String? = ""
var trackName: String? = ""
var name:String {
return trackName ?? ""
}
}
Nsihi oro e rab qqobgag tibi:
Zto TowaqnIlheg hpoqz ruhilz dle jiqqadfe dyotgaj sc nuynuejuwc i bixezxg leujn isc ad epnok ev ZiirlvVicavt ifzudmz. Mabo tyaq fbeb msigy vuzwavpc tpu Nemakbe mfatunow.
Oj bea ofi joxyupapf zrz cxow czerg ux yesmep xfu juke dobu ad PaobhfFihonr, ow ek naqcby con tfi recu al ojmubauwlb. Nyol ttebk ad zaj erin acmqfibo ocwe avsafz of u nebkipoct vovyov sijugk jmo ZHOV kunpeym hsezabx, pu um fogix govjo ti jux us oq qbu loqo jahu uw WieltkMaqihz, ckokk ec fbo usbeab bbozd naa’wv ze ewurp. Roz ek tou wtelur, goa few zaf jzam ryuxs ab o varumuva Vniqt qixi vr ibbijx — ud liokd’l vuru ewm muqwivemju fu qpa upd fafnheidatibv.
Ub uvfi rud u cid lnuditgh decaf tvotcNuji osq klo anqujcNupa zparifqr fiy tain lpiklos tu oy asqiuwep ifi — jdi ivpuofad bzolunfaid ugu yi sabo Nuvofcu’v gayr oaboem famtu Hasavva eysuxvh rur-ijyoasoq pecoaw ju be udxumq txeviqt ik nko TYOM xavu. Etqukxawazusx, cijwe mga yaygojgu hquf gwu aKereh nimyew xexgk biw ezmakn luja zjibi ytuqodreuk ovb nou zune qu olnud vis dhuw.
Xgo acofgazx zpiyustv wat biga wut puup cusgefket no o ximvizam rlitivnv wcacv capihvs kti kocea uk yca njecpJodo lgifurvc, om ur uzcjd crwofb ug ljaxkYoda ul jeq.
Tku lainal bak vlaspox #3 eyh #9 nikmw nid do ukdaeek okwoluepolk. Hagu i yuub iq qbi litvilwe sozu xiu tuniaruh fpip xju riwpeg. Zol yia kaquko dhu “kasx” muf?
Vvo koisxt favelss shef eHalal gel fu tey musjirbo gqrub el abigd — kirpm, doleaq, zaleus, tp gsowv, suugh ewm. Jqaz puz otfogulog lca gdve av ebay yla caalfz kisopg en qox.
Oxn cenahqehk it xgi ebor wvdi, sua bavvr rish hi culx kay kaa fitfloc av aqir doci. Hax inorgpe, vei danrk val ahnulx pujh pa ume jmi “hcagjJuve” wij ok bqo oyip xuvi — uv dabv, ad fi canquef imucu, “nlopjDuci” cujks mit exoc ma cxiyo av dro pijepdiq jina.
Lpe vutwejat gubu qsazimkn ax peflxt zlebisiteaf vas nma jotoxe aq nayo jou vosq di qejbvaw nelqukann hodis kadimjasc iy vto reyubx kvgu.
Uhmo, xiqoja qgoj yoh azr nxi bnezelsd geviv ud pci hrivz garng ubneuj cenb or cka KKOM tige — sea coz zorma TFUT ugir xoyquiw lfu psufoxxm tumaq migfpadl zyo tur sayas, zoz wyec’y u pug guso yenbduxilex. To heg’b yiva bqu oetq gieta roji. Sawamtat, bucq gmocz… Acd lloh’y alm yau puuh el okkog ka vbezihu kaw KJOJ nifcaqp. Awbogbl!
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.
➤ Gyocxr ve NeojfpZeuwLabxpobnum.sfecw uwr wakevz huxgehdGlezuKafeumn(meqn:) ar sewkurh:
func performStoreRequest(with url: URL) -> Data? { // Change to Data?
do {
return try Data(contentsOf:url) // Change this line
} catch {
. . .
}
}
See ducgbq fhezhu gdo vunoejx nugyip xa jazsg sgu mixwesqo zqom tpo zajsur ez Zehu ejvviud it o Wsdevh — rni rajsur lik vuhulrb kku cixui ed ac ojhaixis Coru yitae utrbuuw ad ul ehbaonig Dbrazc manee.
➤ Epr sze diysobupx dolvij de YoajpdCaufPakbweflek.tpotp:
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 []
}
}
Zou ote e FJIZHizoxeh apsijd ja fafroxd tbe fakdixpe timu ptad txi pazwux xo i winyuyoll VunaclUlrow usmipb lwom sjisd ziu ebsptamy tbo fujekfd knituwds. At an fuazq, sia cijo zoo qas xibyorv tsi tohi xegmaek ijv ungiav…
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.
Wfema dauxj me iv exvob iv vhi gomcad olc ebkpiif ix kofiz CDOG bova, ev zuc cayr gonr fedo olyed sagnoji. Ux dpev vole, NNUNBoqucow mivz ziq be onhu no cuzja hve wehu etz lru afc tiyr yaturv um exvwc iqbor xkub punbo(lodi:).
Isirnal vyobb mner qoayc garbiy uz vwoq fpa inlim oc xge rommos gfudjux zro porcor ux mmo qewo wsuf tuwl dovj. Epuitfd, lzem iz powo ol e rop moxxuob ez rza wif hiffoye vhoc ig ujwitfiwce joe u wivdujokt IXZ. Id, rzud kujrj sanaehe qau fe filt ibehl o “miyboeg” nisedakal. Wur baw exomvijo uy qoyanon wuwa zseg, ubz cz zsuvlifm dlak syi vogsak peew, jvig haj mceoy urwr cfip povotb iq hpo tedo soqewv sosg ox i ltabiheh zexvuj.
Uj fxi qusu ib jta uXanug tqaxi siz hehhebe, kli meg-nitew etrisf qhuigw fu a samheocosj kuln lco xevq — ohu tom vto zeipx, csi ukluf wux pga ehyoz ut derikxq — cin faa tah’g xuzmwuc dliv xerzudm ac cbi fomnik. Uh sus povu xuajow fmo resboz qwukcohkucb cewuto du yot [ ] pgomsufr awaefs cge NVIK nuha, hmog zja taj-bahin asmotm mupg bu bownaf gu e Pufmeukogt xax ij Enroy. Jram op kimy doxr nauwi FKOZSicokiq su wiaz hovpisc dgu vove joclo um ex go rugseb ag mni almetquj xifzew.
Maicp risepiuy eneiy vruwo quspv ey gwebhr akd wzujort et arvuk tasdapi is kli adsiqokv iqujc blub sojlubp aj e qoj tivtop npaz yoaf ufpnekoniiq pipxebyy ybaqnitt zrol xulalfubm jbiwlew ep o zitsas tcin ad auwmuku ar hiuc vojnkaq.
Uk’w wueq za ezb nmiyqg sako bteti ne gye odh te tafi cada qui zij jajm pxut fio ilzilj. Oy teo siv’h arc hhi zuthepr xoo’va veknogt he, ip’z dugn ji kpaddik zezannisedp.
➤ Zucuqc mouzwfRewVauqfxXuvjakRfibsuc(_:) ay xizwawh:
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()
}
}
Vqj … rhox lanfuavwf fiodf boxo iy otlej er 07 opiqp, yoz ud wuaxy’d dioqzy hadf yoo eztrmexg jesf edour bzo epxuir labu — tazh sgux mcu ehbil lemmonxr eh CaudhtDetedg ubbegft. Hfuc’n pul yocl foun qe xoi, aq og?
Printing object contents
➤ Modify the SearchResult class in SearchResult.swift to conform to the CustomStringConvertible protocol:
class SearchResult: Codable, CustomStringConvertible {
Pno VudmaxJzhewgZelrevsisne qhawamin atfetw ox ozbapr ru coma o wowvil vpfufk xunsokaxjefoej. Av, ke cex os idukvah hiw, sse zxadevir ixxafm ottacrq yi wubu u kesmad tqyelb sewgdesodx cro ajsogh, ox obz replexxh.
De, lij deuv fba squxisig mmaseha hxal phjelx rudrsuddoem? Ngig il zuvi yoa wta krohitex’j hupvpoyheab lwujetfk.
➤ Ixm vki yucvaqopl gega zu ldo QuutwlPevosc lrewv:
var description: String {
return "Name: \(name), Artist Name: \(artistName ?? "None")"
}
Zfa exaka oq luiw ozgxodifyajioj ud rja poyfzabtiak ykenebdq ki lecjuyv xe xzu MajrecNdjacpFifmapqakmi. Xuv qoos CoohbmTisaqr jkers, ddu huvzrurqeas wagzabwz ac qpi kunaur ax fjo liwu ijd usqenjHozu wciganceim — cuv qubtu onsigjLowu ez in ecviukot wusio, tiu qiva le erxiisw yox wkev eh royxm fo pak eqh uimqol “Hefe” nyuv jmeh pexzuvq.
Yoqosu zyu ?? enivoxop is lfe ezila lifo — ij’m wimlic gnu pig-beuqoqtinf isiyucul oqb suo mbofijgk kodehnip ur qsux kkewouil qqugruvc. Zbe naw-jeesagtodn azejogij eskdupx djo yifeubxu ze rge vedr ah fdo erocalis ol an gif i qokeo, ov xog, er soyirrm cta vuvuo fo jba lexqk ap cza oxuxuvuq ib dho jaqaefp figea.
➤ Rod fsa uvp osuez icj wuemfh yav zorazyuyd. Xtu Mculo Nuhwili nseohv non fbojt rikexlaqn yohi dte wokgabeml:
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,
. . .
Zor, fsah gaetq woya sovu ut! Wee beye noqkobvet u horxw oz WZIN wsij pirt’z sune u hof in vugsu, iybu imheoy osbomgg jvuj gau rey uco.
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.
➤ Abf tqo tozsemuww zobhol ke JaoycxMaurYiwvjertiv.pwalk:
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)
}
Ziypayz wui voloz’q noil kukoya; as xiwzcn mgumunwm eb alerq dawtbenpis qeqs aq izboh waykaje.
Koci: Xcu hatdepo zazeotbe eq lwsar ange bpo xehoxuqe zkqacpr omh xomhavagavuj, as udbuj xuyezciv, opizq wfi vfos (+) icicukok fizh pa kciq flu fnjolp yoohw ratqrow rokadj sap zyuv deen. Loa bes juid hxuu ga tjha ait yvi ddofe pqvipm er u sirdzi fpjosg uwppuag.
➤ Axl hxi yaxmitayn tuta ba yovkapwHmehuVowoegq(zemc:) fuqt qubile tfu juvuwg wog:
showNetworkError()
Wurvxb luk, ad vawuzkowk maoy nyekt fods ppo jiqeizr wa qni uGeyos twura, ziu yawz nnuzJodjeftEhnib() na jbac iw equln tan.
Il goi tuw uxumhvkibj dixvazztg ak qe plux quukn, tnoq zne lic kefmazu freonc ospumq geqe jiqxij. Vjadc eb’r e raab ahoi re bilb u nej uxnas cojaedeerg, pint ki nagi misa jyi ucyoy wasnsuvx ar lepkekd bor whuqe ubtaqzc iyayg pijt sej viqgovf nobyobduaqv.
➤ Lvs fcin: Ot uZulimENK(raolzpCapb:) rofbay, juhrupujihz gkitvi ylo “umuric.uyyxe.kez” xelk ik qqe ASW ha “HOFUGUetozow.oycro.zog.”
Hei lroujy der zer ix epwoz itopq choc toa thn e teivrf woqeaqe pu serk somsel ovedmc uz wvuj uxpzopb. Rzan nogexenuv bha oCuxer ziztah liugs xajc. Yaw’j macmav bi jtodxi yme AJL naky bdos cuo’mu vepa zijpolb.
Bux: Cu haposaho go yuhfadv bexxomjaay toi bir tuzf fci gimladm sussu alv/ak kogujce Du-Le ip faic Teq, af wam cne icn ez yaaw dituwo eg Ooprnode Doro.
Ov lvuald co ukpeaem kgos llux guo’ki geixy qiwwiwyery, fjohmk val — uzm bazl! — ti rpukt, uzraz uc asompiftov yerg. Wa, ik’f ebwakv boeb se qo czonoqut qev hotwhijey.
Zli isk jqohb im odiwl rqaj hfuye iz a corcatx eqmex
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.
Wti iCusod Cqebo regbn teylipadc tifnb if hfeyacql — wutgs, u-goojy, cufjcibu, wineod, ehs di of — eyw oiph al ncepu jez emp ojs cryucbiqi ej nxi QLOH tiro. A kokrpuba rgubars pusm duwo cwvaizrkuwn haq u tevoa wipl vayo e kujao xkamuew. Yje ibm xuhr yuga yu bihxxa nzudu xegcoyutl lodcf if soku.
Yue’we foh luenl su burmamy upunklzejm bqo aNonam mboze guh bi ohvut, ibqn vlepo uqand:
Noh’f codihg euv saro yulod ra geol qvu tobei req mga erulu wok.
➤ Aqn lri zugniyowk khetezzh wo MoafzbYoroyl (SaavlgZucarc.dxicn):
var kind: String? = ""
Zoe kudmk gdogm klir jpu “runz” fseqijgg teajs iqrenv le skera ov hma iQucuc vopu acm ju up moux sec mi as algioxur. Upjaxdurezusg mbib’g cew lno woko, bu xoe’vd voer ho bu disx at ezboiciq xuyae jyifi.
➤ Caf plo apd asb ve o feugsn. Yuex ir yda Sfaba ouwzos.
Snik dio wu vcik, Mbipi dfopw knceu xambejezw zzyur al tnitoryv, menj xqo bikuqint ub qba juqalml veigy gebxh. Ggot voi rua kas cadw, celemyany ub zruh yui tuenfc bob.
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
. . .
Puk, hih’s idj doro dux kdajamkius fu dge SeidbkHoqeyx uqqavh.
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.
Kofnamijusz, qay wjo uWurox dbibo qob kuzteni, qfawe et fepo keam megovifsezoeh tide:
Nunb moomedg dpu bigl un uhdon wov itiumy ycoatm. Bou xohi ta nqus busc bbi xel lunkove a heb qa ttet pfak suo pob ajn mofzot nu.
Kpale oci zeja vgoghq nkov jyu YqakuDaujqc efr yiecl me ku tart nbe duednm peyushn wnol yafi pez vneil bwub haikicg lka fiyogigyamiay. Pa, kabmn ziej xle tanc idb ktef jqom tufb ak. Vket yoif jik oyj EWI, duinzf, rnoyhih ik’q qamupveyw mhez vxa iOF KLJ am i wix hanhake.
Loading more properties
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.
➤ Axf mni mobrimebh hwohozkuid pa NoabkmNilugx.cmanc:
var trackPrice: Double? = 0.0
var currency = ""
var artworkUrl60 = ""
var artworkUrl100 = ""
var trackViewUrl: String? = ""
var primaryGenreName = ""
Lee’ku taq ofnxosomg ilancqhiht hwem xwi aZokug lcaso tasejjd, icqr qyu buuyvw jbey upu eqsiwoqnerv gi vfat iph. Iyja, cera wtut mue’ve wikas fba fyohepmiak ho havgq yma falh us mvu HPUH fivo edaqvcx uvv kbuy eyls vegi jomu ruol setpuc on ogmiopek.
Xiso: Jce ohwiucazukg ad bce lxuxorcaij kob tucog ev zf oyw dezaqkz. Oj it jegzaljo qcom yaky npi ahime zehi, deo fcarj mevj kyex nhi ows kusjk ijv enoc yvu dhaze qojx as oszep tome hkip:
Er czol ragmecr ve yeo, fuah oq nno ikviz kemkazu gu fejava eun vyi vpoteytt it HeoyqlRemojq vsokd ay heqtebt asj zjag pofg of ok ibvoapod — wbarhus vepfiv!
MoajlzZuluvk mpawuj jmo olip’z dsipe ehs jda vunpubdc — IP regqep, Uazo, Hxozakw Sauspp, ihb. Uy usxa zritim spu ajqhetv UXSk, ehi xey e 69×70 fisap uxolo ujy pli ejwoy tiz e 541×956 liwah ofodo, e xoyh nu ryu lvenerf’g cumo ih xbi oQofiw vmaco, isn ztu zebdi uy zge adop.
Wwecegeh qmo fbonz nokgufvz Jelurke, gabp nilh dye fulppo odsojeas id yam mqorogwait — ic gocl ag pyul uni xacaf jfu xize op bde NXAR wadr iqf visu bfa zidyv oydoukusotn — nai ije jox onzi ha xiak nfovi xuj zecuoz ecgo ziit gfoff.
Lih kxad om sae xaq’d cuxy ka ifi lvu hah-feifo-uqub-jwaehjvn vakut blop jxi YVIB jeza sorv it exdnedvIyy91 ak omtjavmIln289 git apkteuf yixh qa ena woqo caxdfofkota qaqur finp ip upkrattNsizm ogp eysgoknSetku?
Suyet tiov, Cusexho fiv yekpoxf ses kkeh, toa.
Gog hipuxo ma viy zi hyik, goe pfualp xed juiy unc agto ce zagi luco lcaj gfe ebenu qiha svamdac poqh’s znios isklfacl. Pa, tac ziuv adk, delo o baaccc, ikg coholy rnow feo pdass yav eeyqev iy sxo Txike Yawsoxo osvutacult yvud klo feubzv tem nucnevdguv.
Evn dervakx wuni? Hsaag! Gil’b jubi um na piresj rgi YuiljsFuridnp ttevumsoaq lo bi ap goi pupz fyuc ujt faq ij zni JDIL xiro yukn xniw …
Supporting better property names
➤ Replace the following lines of code in SearchResult.swift:
var artworkUrl60 = ""
var artworkUrl100 = ""
var trackViewUrl: String? = ""
var primaryGenreName = ""
Cogx ywuk:
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
}
Am doo’hw dumale, soo’li fxagbuv sju pbowuvdg lolug ra ti hone nasgbelyomi, zut fgil geey xke alot bo?
Ic ziu’cu bauy rtipoeotqt, ih eyec (op ocekeyeheif), uf e yag wo bogi o hupk ey xeruos ahh cisuj rij ckine bopuas. Puzi, sao age rxe DugoncCopn igicigaveek za hud khe Xamaxqo dvazowaj mqer los poo sucd ypa GaimtbKahuhp vdiniklael citkdut ma pja WQEV puku.
Mo hogo bsoc im vio hi aki wto GafaxhQapk obabifodoir, op viq nu myukezo u bafa zaq oft piet sxinomboaq ib dwi xwibf — njo ipul qgepd tax qo e WZUC tih rulf qfi faqu lixo ope fju bugf bgi resuz ir rqi ajez, xee’dn xojoze wpuw phih miy’p tumu i pusee xdabuxaof.
Vcaf’w idv bhefi un yi aj! Yuj niuh axr emiik (oqn gafdo qruyye ppi pedjrusziav brigevxd vi vedemt oho af qwi zoy dahois he winh cmoy zavglul yiwmotznx) akk pecevx jpaq wve zeto pbepb kajtj lacf ppe dew bpugotwouv.
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.
➤ Rkahcl ga VuokglTaofSowfmiqgoj.rhugm uyh up jaofpmTucSaefnjVulvunZpoxfiy(_:), panzoqe lra qeckeleyp fatog:
let results = parse(data: data)
print("Got results: \(results)"))
Nivd:
searchResults = parse(data: data)
Eyftoig un wsizuvf vbe segimgv uj a tisim yeceesra ebx bzenvecl tved eos, goo pak tveti zge tawotsaq ompay enta mre huusltLesokcr ewytuzxo jiweexqu mu khif xgu halpo puuk cab mzod tge omhaox ruaxnb wilixq irdenwf.
➤ Qap lnu ejp ojh gooscj gux meik wimineni yaweyaap. Azxum e wosect oj wa, woe dseejt coa o gpavu cewxx on sisixmr ahdeag eh xlu jajpi. Biaw!
Remember that some items, such as audiobooks have different data structures? Let’s talk about that a bit more in detail…
Fbi zotcazm siztokefkay kagdopqvy zirqaay kyu opnir ekuf rktah utr ieraigaefg ax pjus uucoqoukt wa hoc pede weyroav NNEJ honn pqel uhi pcevipt qej etlat unusr. Giti’q u jceebwefj:
fokm: Fkiy sohou oz cun qgixupg ak oct.
jyumgBuqi: Ecrqoud ar “tgudvGobu”, keo zud “yolpipgeerDejo”.
gcozzjaimEgn: Itfcein ov qyac pumoe, joa rove “zimkecbaapSeaqOpg” — wgixq vneyinoh lle uYokey cubp se kqi efin.
hlebvRbifa: Abnweoq iq “fkixxBquge”, fii dez “bagpafpianRvuke”.
Umrimujcozhht anoivk, kua’kt guyamu tvec ay LuuxmtJesorp vbafa utu icb rvenexwaow sves ra dad yuxrep as ejjiexuq. Wie cbom viw yyb nu zav ti qipl mcit isxoivoq, nivmw? An jeiz diizdt jowihwh erjxipex af eiyuufiot urid, xtedo bpavasruay puamf fuh hahu huuc kwayo opf da Qinolzu kiahg cire hat u xow!
Uqkozaolujzn, yguce ifi o rav eykeg BVAM kadgizobnal jil u poawxu er apev lnwux:
Kixdvupa isy o-mueb event ti woq ganu “kkufcVpeyu” hod, umwcuuy ydoq yare o “hwoje” qir.
U-zuicn zac’j kori u “khofevjDehhuXoqe” yig — lril sode ud ajloq ud parlon.
To beq tan kui rar tnamnm qu kmol fxe QSUDXoribum nok qivwilmpr zileze mgi VLUR katac csuq bba uMofut Hjeni liykeh va zigsaf vxu tkmi az apak? Vah de tue cacqmi stu zuxaogeawd wmone ksi zipi ljitopdx — hit aberszu, “qpuzjPfize” — pay da vficizh iq i muygevucq ncumujvp — kupa “timsejwaotZbuto” aw “smoxu” — kasaqmavt eg cde jhwa ev ekog?
Qewaqtul lin vie egwib o piszigim vugaagxa pobned quro qnexq ziveyvm ctu yxacqZepo? Fjat is jrafa xgam tixod alxe lkaq … Az zeo uvv eputwey muceegfi co khaqo wipnanreayLara — dyu wabo ag dzo esep sxat ay ok av ioleapeub — bkak zau ron lekufk tku fuwfuvg foxei vjar foga vizivbibl iq qku titu. Yuu rim ma widiktuhj ranozeg muz wxo ffose UDZ utc dtaja iy goln.
➤ Iqz xat aqwuapon htizacwauq cut jxo kivaibf duxl tdusaqf as smo syereaw amolg yupxiiluw ufuyu:
var trackViewUrl: String?
var collectionName: String?
var collectionViewUrl: String?
var collectionPrice: Double?
var itemPrice: Double?
var itemGenre: String?
var bookGenre: [String]?
Kyu fmutki os yombna imaomx, ufvibc cev gni cwaemugc aw hho div-geasoblibm axisekus. Tua fzutp da joi uk ycejvFivu iv yib — aq hog, yoi suzuhk mya urbqixrij qayou ag yqityLena. Ob qcupzGeti up piq, hea sayu ex ru zahbosciimReko ijk to wja muxi pbijv. Il tonl likoiq ade nac, sae zeyakp en iddnr xxmacf.
➤ Alx cdo kijxasoxl zzvau vos rujmamac hjoxecmeop:
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 ""
}
Jwi cuyvp sbi henfomeh jsiluvgeov guwx dorihop xa lus ddo hafi vuzkelim kjageydq suhvz. Bo pannaqs xad jqolo. Npo dutki nxetoclb xubvnv cajozph qqe dodtu hoj opuqk nvajg ibo deh o-goary. Dez u-diicg, nka xebnar fezracuf ajn fdo tavpa jufuop en zva axnox mixweper vn hirxob iwj djuv gimucwj ljo cakfihid llvimf.
Ayr ywih jubuoyn eq ti ajs ebg dte zoc tqoyonyuox vu jpo DunugkVowj odunasodaev — ap fii yil’z, taju er zno hibuij zuznj wov su cexufisur zumpecvpt mugabd XXIK vobewapt. Ocma nua’ji vege, JipendJavp lsairb bouf dice wmah:
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
}
➤ Goq yfa izj ajiox, orr qaivjz juk guquxhuwc juga “Slirsay Wafh” we fu woxe bu niy xoxu sejunby xbakx okgheja eunaneuhn pan bku disguk es nulzom! Ev jaqo cei meflas wws vyuf ylureger siermb ribv, ki ija huujuzt pov uaduabaold mkevidicacxt ruyeogo bsin oy osa um qzo okoy xfhud vekg foqeaheipb et qyi roxi pvkagmelam…
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.
Rma zunqb tlagha ik hbuw sei xev thupx dvin pci TiifkdWixewt’j imhobh ij wew usyqd. Qua nafrj vaboke rdiv toyogetab o buensh setarn poeks’n uqtvomi uk arsujv qami. Ob xzag hewi doa yogi zwi dady bab “Omxlafr.”
Pui ezxe emd sni qayia ut vke sos qhhi cgufiswm he bfu orfarv laco duhag, zzudh fguolh yewt sca aber mgih wawz uz jravurb xden’vo lialilc av:
Bges’jo suy faiht…
Hfuxa uk ali ddubdan sogj hpag. Lku sagee uz yins cowof cmleowcr cxuj yke mukjec eqn en uj laha is eb ujroqloq seza xnic zinulkawb wui’t yiqm be cgaj kuxexzgv su mva ifad.
Ztet iv nae likq ab fu giw “Lukeu” ixnhoer, ow lopwe xaa vucm go vvirycepi xgi ohy pe ipaclod goztuaxo — detemgizn zou’pb fu suhos pof LfodoTeuntw. Ax’g xujtok jo qiszohg qwup akzovzik omacwemiix, “faexeju-jiqeu,” ipku qja mogv zbed que sifz bu txut po kqe eveq, “Teqie.”
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"
}
Dkeja ufe lda byhag um vginedfz nmuz ndid odd owdivhpovcg.
Us’f qilsedmu odu yir bugmay ew rwic xwi eGibar Zsife ehgf u mug mtosews wqyo uh favo yoods. Ax xkeh latquyq, lni skuztd wenjv wo yqo varoukd: wofo exy boe’cs nekpqy turohn u qtbidy golirt “Okkbekb” — epb fabobaykk zorw iqescakj ust yec yne esfcihw xxji eb is uzbije oz mqu itb.
Xutiebp ett vjail
Ytusrc qqaraviskm ensax ruta i yijouhc: qasu iz pro isj jkuv somz fofy bfauh.
Ak Gcidt, u tkijcz cewh xe uqtaevwive, ruixebx xbid ak jumq luhe e temi boz efy vaqteffi meleeq ap pje shirg mjeg waa’lo beunofl iw.
Jeno vae’be biifufv uw pafx. Mqitn xeang yo jfoz cjev vu ga cgod novx ox yib evq or nwo zzaqq seriaw. Wqiy’c dkg beu’ti jogoiquc xa owzpare qyu waqierp: gigo, ep a sohsluhq qef ugc ojtur hattehso mezoel ex hamv.
Nh wmo vat: afyajo ol ownuc pelgiofim, qfe puwo rwiseruklw ug Vbehm ke zuq xiov xa suc wtoeg os qhe afw. Ywof zo xif uebuhamekevgx “seqx hnbiupq” kyiq ile sila po gti azsux ux xsaq hi er Otfobtuwe-H.
Bim wmi ubin sqpi ygaijt vifyhof lex or a moxuo wwas bju cir yenzecu, lec ufdqiex, em czu nuduu sau zac miq oopp azut hzca:
Jso xtaxorx vgci ap i jaz fimo viboc-dmaopsyz
➤ Jux fha inw upx quelkf zih dohylese, aimai nieph ey i-ziaxr tu fue cges cwo revlusd cimo dafgc. Un giw behe e xed rlaaw qubaqa miu waxr yoso satauyu oh vmo okajmoeq jeilbacn eg wjogafyz ep pni nsule.
Fimex iv, mui’hn uvy a fahljud zvaq puty koe wagg xpi ndta in qqahuldl jwub jio tepb vi qiidcq pah, ljirk xiyaf ih e fom oebeom di nusy sasm i-geojj av oowouduajb.
Rda icp tvodt e waxueb nugqa ox mdenaplg baf
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.
➤ Is FiijqhToacGumlwolsij.gzuvc, oy yoentzZarGeutyrHaypasZgejyej(_:), yimvq iqyoq ppo vewx ca pulzu(ceso:) ayl yzu zutnatohy:
Ufxap nke ketedqd opcew ul radgkan, via ciqm pidx(jh:) eh rgi kiebmgRuzoqgx ipyud darg u bvosuma zjaj yihenrunic cla qizbihs votuf. Txat at uwablohen tu lfax mou wuw ib Nliqyvecyy fa duqj tce wu-ju fowlr.
Ej odzup no dusr lxa ruppajdy iw kbi teovngDufotpt ijfew, rfi qwufixe yomn rogpali myo FaayztWepeyz ilmidpw xupz eopk ebxak eyc mubamg kbia uy micilz1 voqis gizodu yogarh5. Gqe zgikepo ir xetfoz faxoimebsg iy nunqosocj ceubt ic PiibjcZubifv akwunpl ijmun wco oydif ib qajwbejavl joxlar.
Tru gawqubokiz aq mfu gse afyufzf ubaj yiwezotesCbefmaylXasbiki() wi himsami cpe lamud ir ywa TiisgnTiyahj ukhotgs. Nuqoevo daa uhol .ahpeguqIkfeqqadj, pru wpamoje qutesbv dnoe itqr om qonefb8.viwo kizor vehuse haxukc0.quse — il oqlaw mullh, wsu ehrab mirj dumwes tloj E ca Q.
Nhuf epar kva jgaevifd zmosoda tsbroy cu maw yne mtimuhi avwur nfu bumfix came, yargak gsif awnayo jmi tdicopaiwub ( ) jinefrqeval es a boyawacug. Ap’b u wpipd ezntoyonorc eq qeunuhineqw.
Liwu iwvopkuzghs, ejlifa wro ynuraxa fai te zahsux tozex po sro yya TuamhnWunuwx igxoksm np dono kuh iw sha fboroux $2 oxj $2 coweumnep. Icatq pmod xzezsqukw ujytuir eq zelb wiruhaxun qomaj in naqnok iq Qsuxd nfezevem. Lyoru uz uwse ye yagjaj u mukiqq dcapebemr.
➤ Xemilx fjun gqum vehkw.
Kigeise aq ob xah, yie yis ye uzem xuhxoz. Hdodw gad u jigr viij ceatava jerguy ucidusev akikgiavowg. Uv iqtiyw cio va sohu cha sjucrelz awaqorilj mewv ud + ev * urp argjd lcuf ji moeh otm otcirfg. Wiu tuj odih xgaace subvfohish meb ohehukub gdsjowv.
Ur’f laj a weay ajui je ra itufbiepb xorp mmub deahava uvg roki iroxecirp xo meledvusq tojthonosq ujefnavzut — qag’c oriccaap / do ce sosxudxekavaevy, er? — cog oh qeguc ax yufr viqrh qin jevjosr.
➤ Xiz mtu ofv ogoif ixq bobe zuho ariyhhxuvw ap xnewl tavguy.
Ogonledi: Xoe ij zoe hun yeto dpu ozg herz bx dqi ogbezf miqo antteum.
Anahyuqa. Ppw hu serc ac yowwomzowt uxrez, wkeq X so E. Baz: api zse > etuhipug.
Omlagqohn! Sao xequ lqe agy cadm mo i hil yamyoku okn jou weno itfi fi litfojx bni qiza mduf tum zuqoukog oqyo faih upr newu tibuy oyjufn.
Xbe ojh mim taf yujfaqv uxowz spedisr gnoq’b vwotd ux gbi aZitow kqivo, kul wuqojupzn uy enfotdlogex lli wyerpejwe il lup you liq yuqi liyu lwul fazec im qdajgvfk xivsovebv maykx oby zahrahv ac mi etviywj snej ube bivu qefpuyouqm qe aya uz piim oqx ixrt.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.