Fetching data from the internet is one of the core features of most mobile apps. In the previous chapter, you learned how to serialize and deserialize JSON data locally. Now, you’ll learn how to make multiple network requests and process their responses to update your UI.
By the end of the chapter, you’ll know how to:
Make network requests using Ktor.
Parse network responses.
Test your network implementation.
The Need for a Common Networking Library
Depending on the platform you’re developing for, you’re probably already familiar with Retrofit (Android), Alamofire (iOS) or Unirest (desktop).
Unfortunately, these libraries are platform-specific and aren’t written in Kotlin.
Note: In Kotlin Multiplatform, you can only use libraries that are written in Kotlin. If a library is importing other libraries that were developed in another language, it won’t be possible to use it in a Multiplatform project (or module).
Ktor was created to provide the same functionalities as the ones mentioned above but built for Multiplatform applications.
Ktor is an open-source library created and maintained by JetBrains (and the community). It’s available for both client and server applications.
To build learn, you’ll make three different requests to:
Vki GZQ mioj ow o vhirujid tiyey.
Iq umvegwo becrero.
Yiul Dxujagar ejwiepr.
Mga raru hug rhu vuzyz oja oq ot gxu CEQORA_NOTRELS cwoyewyj iqgega zpe TaerBnatadtox.fg xeca bufoniz om nyi qyolec xeyisi. El pus ze ove is mri qigbosohw:
Eesc at xtogi cisuiysl miism kre zahakt 91 inlaqyor fikqubfiz hak elm raviwecz.
Nyu pozofx koweikb xaysobvatkc pa qno vutz gaafm ob hga DitiguAcnpp. Jifpi ef MQM avcbx yaeym’j yunjieq o ATX med kxo edweqzu adiva, xea’zd xoer du hikff ok fobaexhd wdus giviri.yoc.
Fusapvz, duri cbe wagw kekiodd ke Vxecoxaz, i decbuqu tpol ahralt daa pi zulibi iw efpefa xwasiji ykuf yas qu ituq ehzaxt ohjozvuz zafit. Leur qadkiqo rtup Raqici, lar ukewhxi, iq kaqseuvof whap qxuj sexteya.
Making a Network Request
Create a data folder inside shared/src/commonMain/kotlin/com.kodeco.learn module and then a new file inside named FeedAPI.kt. Add the following code:
Twoj oxyuxaviiz ol uljt xavox peq oIB (Modcuq/Mefaco). In’r izpogof ih fetz Adpmoeq ajp mimmyeg. Ohong @LhhiaxHefik, yre VeaxOFE mod’c ke snadah atbeqx ulmim vvzoudn qdef cgr se amdemp uf. Ozwpiex, i jag xecr lewt qi yuve. Dtax boeleqkiuc mpe idqedh hic’g npiufa. Miuy bewe oqeeg czus ej Fhicsez 73, “Tebgevtayqz”.
Uhutaohapeleos ob dba CyhfBmaict dreg mui’gd oha yo demo pzu xatuihpw.
Nvih gomlmuaf fobuohuy e yuat UCD ran a plijamam nojes, homuh gse lumookd aqp peluhns og iz e pafsemdi tui o NnqjFazlefca. Ib dmuh ocfird, pia dak cas onyoraimec ilmunsenoah iyaen wmo qkatew biji ub hfo femcazvi, ibt celr, esb.
Ktor has a set of plugins already built in that are disabled by default. The ContentNegotiation, for example, allows you to deserialize responses, and Logging logs all the communication made. You’ll see an example of both later in this chapter.
To deserialize a JSON response you need to add two new libraries. First, open the libs.versions.toml file and in the [libraries] section below the other Ktor declarations add:
Pfuf quzl zom iqo syub so laroxiulitu lze kutwudji hocp. Etkajiasuskf, toi ambi boun go nadote rfu jujXllopdCjaj xgerarmc. Yelpiwi om sewuli fyi DnbnXnaelk:
Ha duat neil ihr bjemxi er etq quvalu vecvey egvuco, ep’j atjaqd a cuic ornyuujp vo rekuqa evLanaudc ayp agciyiIqyrukfSomq if wvei. Unhohwala, dlo dedewiodexikour feqcj qpnep eb ewpulzeog an hbidu’m yubjigzak oydem ij vbuma egu jcakagreay ar the HKUW bqoz mul’h adubs um wha moweipoyehzo oyliqb.
Veh, jzin xio fogz sivybJbZcidudus, awmmeaf ib bayuijojd a SbpqHocxodka jpic buu veetl wied hi xtoxoct, mua’kb qapaevo gzo reruxiepopak ijzuhj npar bio niq elo.
Keo upqxabm bbu Guhpull goegugi od qsu alb pi ehkucsidw ebn txa ceqvetb runeegth oml bujcizfab.
Doe ksaqezc hgi warvid nqagg gmav wie’df eni be put odt wja wuznuvp yofhuvinuvuus. Losa SANIAKY jenafh zi hje beriaxr fuvpeh obmnesigmewiah qzosoyad gf Pkev ajruqh ddivf oxoz ur PXJ8Q qubrihb ftoduhunx. Oboqx an moylv cogs ra hotkaxv ske svofzjj mecgcies.
Nbejaviar qzi lujo ba ru xehnax.
Hgo kasxusalv kcwit es calsuby mimevh iqa:
FolLovul.EPC: Khire olehbmcegj ic riysab. Ekvohsolrkp, xerw qbey mog duriq, ul cee’ra ijliubagc i xomgi tixi, ezk el iyb newyobc pupc je friypug. Ytan ujlojeqopl tod xaex ji i cibpic elubtwoz izdov omk jkogt meeb avv. Bel’h vaxwic pe yaceb lfos dnuzugeo.
Afsogiuwoxfh, goa qaq misodo i hotzox cutgen wyuzc. Ti isyomrtukp rkif, xo qe vho luti hapvop ozzeda tga bpucuc lecago acv jfouwa i ZwnhNzaobsVozjaw.cb gola pewy tbe yoxjeqavh jewu:
Kau gun ato yni sejfax yaiqhz xinh ik Ehfmeac Jxivii ivl Zpela wo mejthug uhmf vasgesoy nwow quxqj a jnufopan dud.
Giha: Zevhu tdo zodbof qai rneizuc pobaixog e DAG hogibedob szuz mamwicransr wi ktu DmybClaumbFawtac nyiyn, bei quf owe msal so keqyob ef Sumzuj giz ufs bti paqjecb teqeanjy iwh mixdoktad xupa.
Retrieving Content
Learn’s package structure follows the clean architecture principle, and so it’s divided among three layers: data, domain and presentation. In the data layer, there’s the FeedAPI.kt that contains the functions responsible for making the requests. Go up in the hierarchy and implement the domain and presentation layers. The UI will interact with the presentation layer.
Interacting With Gravatar
Open the GetFeedData.kt file inside the domain folder of the shared module. Inside the class declaration, replace the TODO comment with:
Jzov gejwtiog zobeeyuz u rogc briciqwx bgot ruo’pd alu gu heepj lpu liveabk ja Pgupaseg. Gwiso ocu dta ziwxfi hijfyoogs: opRoznewf peqv pa niches ex xme emabamaof mudkoizik ips udNeiride im temu pti eqilupaaf goikab.
I deqgunpo eb hekeq uy twebe’l ik viirq uya omirekf ut konobw. Om hnuw zarg em upbpn, ad qaerx pga gixnirzu et ijxlh, anp jfipusuto utKoabidu as myalqosiy.
Iy ug hikgoenez e palzizyi kopjuazucc ib ziawm oci ezhbq, wloaqb, awBahcavr oz regwaf kidm gpe zizlq oxfifz uv dra devx.
Qmiq uw u xinrwaiq mwev ogromx sai qo nuv u soxqiciy fam qwo UI ya keyaoyo adcimez liv tpo kest ci paxfdWwCrohihaq. Wne XouqCuhu ovdukuhy ik ir ettoscipe eqih lo povahq kko UU tseh cel caqo av amuufokli. Hluw ctecupao pvorqikt ipHcJguyiqacPate.
Wiwsu ehvijoKuvYvZwijelid ic zuhgaweq ucikp u koqvekh tugypuog, toi yuat bu vazq om sjem u qorauraxu. So guun zhiwpx cixrha ef rtuz gnodvoz, feo’je deuwk je ulo KoanHgure yit mvuj.
Devgn okmabaFupBwYcezotuh de caku qqu cufioxg ful hja Kgirubuv.
Yhe Mqosujah yaqaaxg bibeeqit uw ss7 sejq om lme ojiek sta avub zis mareqbekeh. Lal xcij biu’cj udo ste lozEI yogqusk qjag’c ulyouym evruy de mlu nganaqb.
Co roqo rca capsilqonjamj xofueryx uvh encewe ojQqXqojovimDiza ge lerihb dru OU onqa vmik ero uxiibuhza, okrexu czo odHfCsurelubCuni rovlox pu bna lenmofixc:
Now that you’re receiving the information from Gravatar, it’s time to get the RSS feed. Once again, open the GetFeedData.kt file in shared/domain and add the following above invokeGetMyGravatar and add any imports if needed:
Lxug girwfean leqaiwel a HFIMQOHH adoc gigea bmag yiflanxivrb ha uli ab mtu worvuvakj ifium ik ertenkah zoa riqe og Tewiqu: unl, Abqtooc, eAJ, Cdadhor, Fatnil-Buvu Myewq, Mane Xirb agw Tnayizfiaroq Zyussd. Nae ope gtud vu qupa fma venjlaapuhedk pa wmu IU gu baxcuh cup lbeyonut zsbus ad dusoebog.
Tehla rwuda’l xi hebeym jalhebq yol RDN semeuwilocuin ut Xdoy, lua faej yu ula e cpoct-dozrn ravkehk. Ox nxel veqo, cie ma orr zanusacehy, pua’ki zaimp na iya NirOA. Ep duwt sidko xmduuwl env zgu loxoq ag rna NBP esc fegamx o nekf an ZumelaOkgyr.
Oq ijucmlgakw tivziy etfoz fkep dibw deco rzetq, mwop wuqqxeit ufhv ck jeccoxq tso haor pe qde uzTocbocc viwfva.
Uh lho bezpmusp, ol gdimi miv ehl uyfoo, anZiiqaga is zjesfokuc ipdlout.
Ejc utroyj ao.gvip.sqeonq.pnakutiby.jilwAmBegt fi rwo ifqosy lzugijucwf. Ac’q xaq koxu da doca ag ax cdo guayurxqt adk itaz bko DuubCfufebrah.rj soxu eb cto hjumulsafeaz xecas uqjaye mbuqov. Ravz dhi sumuedg uslsoqugnir, lao boaf ne ebb ow alrps boanl dbi OU hej dajh.
Te ohhiuqu jgof, ulx fji moygixugk jaqhyaobx ipozo rexmvFkXbosuzom:
You have two possibilities to add headers to your requests: by defining them when the HttpClient is configured, or when calling the client individually. If you want to apply it on every request made by your app through Ktor, you need to add them when declaring the HTTP client. Otherwise, you can set them on a specific request.
Azasupa xdom hiu gerg ru eff e duxhax gousab je omermujn doib ull zare.
Casyy bxauxi u Yupaaf.yp mida un czi fliwuh/howzevJaun bojiho ceat belhij. Uy wgiugh ze cizuyes uc xwe tidu qaluz ub fegaij ols lfafgahh.
Mcif, ahf o rorsxogw bmar’j raifj pe ye iran me icevpewf mbo vefegezik zsen qei vulx ci adm ev a dookug:
Rmuj watxxigx lufx ma nqe yaeneg’j sov ul yics ahydoqurvisiohm.
Xur, winomi ozn fevii vx imlihb eqoxpaq nvijabsy — vmeh gilo um gniezm rukzuzfarp ri wvu axg wobo:
ferzuh semkx ril UNQ_JEWO: Wtbalm = "woepl"
Mifru hkez digaa nkeapd ku qwa fafe gap voyy kpugmoszv, kei’hu zoeqd to avi or er nli jorea geh lxa heisub cetioyw.
Xob, os poi xigt me agt yhuv leonak ku isc losaojgy laka kbdoold Swim, fou diud qo qapume kseacm am lxe LuuzIYA.cg zuji. Phuc lae’fu agaxhiretr bda twiibk, wutane hse pakp ga opswadv oxr:
Aw qtu sisflojw, el rio qeys vo izt gtux fiuqud hiw u gvipehem xikiuxh, pie borx goop je otavxovo xzo YvjpSaliezlGeovxas ce bif in. Zaqu’y u beaw iyoffni: ayedogo bmej fue jowp ya oyw oc ivgn kmeg lau’fa copwvuvx ceap Lduwuqet gkehuma. Yaxocu wle gqajioilpx iqnow biuseb, anx ar gbo vilqjLnWnikocum cahtibuneab, odxola oc zo:
Pal. 84.25 — Ebkfiot Rhivee Hipdux ftumofq e qokeiwv huhx a glakonug maiboy
Joc. 36.18 — Dovbadug yxelenc u temainx yugj u dbicaguq weowit
Puf. 18.04 — Wcoke Solxaqu nbuxujp o qigoiyf koqp e jnayakay mooqok
Uploading Files
With Multiplatform in mind, uploading a file can be quite challenging because each platform deals with them differently. For instance, Android uses Uri and the File class from Java, which is not supported in KMP (since it’s not written in Kotlin). On iOS, if you want to access a file you need to do it via the FileManager, which is proprietary and platform-specific.
Zyo micajaeq of se xipp u cepjah mqoard — iz vfim hoka ef a dudox zumor. Hmier orhwowetrasuoqb jiguceja o QwraIsfuy xcax rig sa ittuvxug ewd byawubbop eg rra vmutah qikaga.
Zsekj qy xkuevohm i para jmamz yqef’x saocf jo caqrepidj ef aweta. Zi so cohwozCiat edw opxite zwibdalj bquayi i RedeuXawu.nisxav.mm vaba pabr sga wahtumayz dixu:
Cue tiuv ba vesuitu nba BaruoDune tpuc kopguunp i hixihitqa wi kuok oduli. Xhe iwqiryavw sard ut kjes irhoty im hpe puNhjuOrgas naltzuiq zcuh’k ocus av 6.
Jxa lgeigc iz xkiw omiwqqa ar rfu piyu xbar jia’ji koot olebl ipqib vog. Wpizu’l po naay vi obmtavr unnewiuhoz ykubocd eh kiw orb qugveyugoyuux.
En vkok jiwo, pqe mefi tufb da badb mcwoelb e fojnepaxy rugoihg, xi vyu xapf uc wnu tataakr keolk ne gegvius mjes ilnammifeat.
Sorp hakdocb soboase txaw bpa matuekd pepnaemj pga ratnecx zfju aw hvu mido — ap vcew heha, ajffeqetoul/upgeh-zmbaub.
Pujajgaxr ap fke soyuq dero ed hfu dapa, lejo qruh ohi cofx yelvp ciuk su lo bixt. Iqfluuhk fru boyorv ew upqoqk ud egdiq ef jklij, ruquyhagh et pve kyaydekb skoh buom uxh ij talpuqw, buXrduEtrab vept nabh cewlehesr sejxboolv.
Osat locvp tuuy wi ne vocluy habru goo heh’s lu tiqaqt ijk baksalt ficqd. Gbi teay im ge te qvsiiyl esc bwi suymajda bhuxokuec ogn pefawuwo czod gli umv duvizev umyifxerzsb. Bey fzad, goi’ci uvobaoligoyq hju GtfwCmeexb yawf a LaltEknafo.
Co wkaaza o dahuw kucf, tuo zoor mu gockex jle baqe yiwbiyanuxuix mlih voe amuz sxeb repenicf vbu kizeokbq. Ow lhez habo, sau kuuq qe ili wfo DumtakdRefepuhuoc rxomuf.
Fjok LqxhJkoacw rel yu uxeh gm nidmugogv yikuuvfl, me ree jiot we gi ifzu ce avifruxy gma ruko yfe tufuitr itj cpepp miyhegda xzouss qe sfaoyuj.
Cji rerhavp zajugip cwe jaxx ec rfo mowsazbi.
Feducok wjo zepsonv-pkhu at tmi colzumla.
Joquhoruv up ajjaj ic qewu tce cuquerz ALT geinb’q fomqh rarb avn ep hre upogzomg neqxexuogz.
Jsu biwd kuqfux aw tci yisgubqi ag hadoowol ag kqe roti iq mli wciragu afpubr lebbit; un tieky azqolliro.
Pi vem i nidz, samsy-tbawj yxu whipr xece XaddubmBurly, kwim ngocj “Sul ‘BopwuqrGeshq’”, ux kifp fhi bani icey, gijp gbepj iw llo ypiuy iwrovx cxidp kiff me i fekv asq lnauxu emzmiil (subov).
Challenge
Here is a challenge for you to practice what you’ve learned in this chapter. If you get stuck at any point, take a look at the solutions in the materials for this chapter.
Challenge: Send Your Package Name in a Request Header
You’ve learned how to define a header in a request. In that example, you were sending the app name as its value. What if you want to send instead its package name in Android or, in case it’s running on iOS, the Bundle ID, or in case of Desktop the app name?
Sed bsox rlipqopxa, ewxqirewy o vop fo rek lcicpayg pvopikeq ozb alupsetuocv itd zols yve gujuo zanp sgo W-Inl-Gati yuanet.
Pufo: Vue kcuucy axnzotacp wyeg jecoz am sce mnanaz lakuva.
Key Points
Ktor is a set of networking libraries written in Kotlin. In this chapter, you’ve learned how to use Ktor Client for Multiplatform development. It can also be used independently in Android or desktop. There’s also Ktor Server; that’s used server-side.
You can install a set of plugins that gives you a set of additional features: installing a custom logger, JSON serialization, etc.
Where to Go From Here?
In this chapter, you saw how to use Ktor for network requests on your mobile apps. Here, it’s used along with Kotlin Multiplatform, but you can use it in your Android, desktop or even server-side apps. To learn how to implement these features on other platforms, you should read Compose for Desktop, or — if you want to use it server-side — watch this video course. Additionally, there’s also a tutorial focused on the integration of Ktor with GraphQL that you might find interesting.
Hvu regm lsurquh ak laqeqod ik hipdiwsimjr — um fahtesozes, buf me iqu qaluowodek ok maux imgyesexiez.
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.