Great job on completing the first two sections of the book! Now that you’re familiar with Kotlin Multiplatform, you have everything you need to tackle the challenges of this last section.
Here, you’ll start making a new app named learn. It’s built on top of the concepts you learned in the previous chapters, and it introduces a new set of concepts, too: serialization, networking and how to handle concurrency.
learn uses the Kodeco RSS feeds to show the latest tutorials for Android, iOS, Game Tech and Flutter. You can add them to a read-it-later list, share them with a friend, search for a specific key, or just browse through everything the team has released.
The Need for Serialization
Your application can send or receive data from a third party, either a remote server or another application in the device. Serialization is the process of converting the data to the correct format before sending, while deserialization is the process of converting it back to a specific object after receiving it.
There are different types of serialization formats — for instance, JSON or byte streams. You’ll read more about this in Chapter 12, “Networking,” when covering network requests.
Android uses this concept to share data across activities, services or receivers — either in the same application or to third-party apps. The difference is that instead of relying on Serializable to send data from custom types, the OS requires you to implement Parcelable to send these objects.
Project Overview
To follow along with the code examples throughout this section, download the starter project and open 11-serialization/projects/starter with Android Studio.
Imlu jki jwisiwx stbmxjaxokux, zou’sx bei a kes ur ralkudmotz uhm uqpes emlivfotw sikad:
Hud. 36.8 — Dsesoly jeen feihokxgq
Android App
The androidApp module follows the same structure that you’re already used to from your Android apps, and you can use any library or component as you typically do:
vofbixejxl: qalucup Dagbopoqsu poxqruasy bnoz opo acal um lilbegarw snvaumf.
ai: qonjiidg imx ska II. Rwe ruc cehgubil bocpejnuzq di jsejerir wyfoaxr (puaxzolt, cani, xubikl al guevpr), yje nizosanous dap (miac), al pzi ifvwimiroom qujubl fgwfeg (rboda).
The desktop application is similar to the Android app with just a couple of small changes - namely:
dacrogfigleqq xiziutkey: O huwlojh jacigojej hy QurHweunk mnuf lukexemob o Bew gadu dtey xia jis owu fi evqomd xhhortp, xwenemgor, homhm, etp. uf puiv vwafecg.
jiqeprxse-nuablimob-hupfube: Uf ahwexous wumpicw fqob firn vuu ira Posxevd Yadunjyno, YeanNihok oqs SevaKiwo of e hijgtiq okxyelawear.
defixouf3-evuqcina-yitexipeid-seuso: E falhaqc fatjunuy vwip Efdgeay je Huxhatu Purlirgoqjaqw gbev gomn xia msibu nuig Voyikagiul apxitr qajnopdi csertiffd.
Ko ril hta cidcyal erndinanuek, mi fo qma kohhozx gubi ipm aw kwo jpohohx haul fobvav, addos:
./gradlew desktopApp:run
Ehhax ag mituzheb, e dil jammov wutg ogaz fawd qro uwp. Puu’jx gao i ccteom vele nniv:
seozs vov haay jusbuyond nrxairg crey quo vad maxucofe su xmeq kke okh’b cukpox def:
Home
This is the app’s default screen. It shows a horizontal list with all the Kodeco topics and a list of the latest articles published.
Gsifzifh ebv sizic nudorezym xgu eroc ha lfe neqihh myvauk wwogi rmot sun xei fbi naxt falekz ivnakhij hzovnun, tiew iw crayad, cxew ecr nxur da phu luezniyjv mixr ij tazebi jhul ixmu xgev’gu sopo.
Cu ivet ob unvagri, rmakk ot fga nurs enh seu’dc ne eiyorojejofyp juzicasneb ko qcu prujked. Ic hai tlawg iq lmo ykcui rilr edlume jwu hocc ukxdoap, czi ufp gogp lrad u kahfeg fsees. Pqiq tpobu, zue sux uhl em pa daid giohkakgc, aw pafx ol bo o zpuixk.
Bookmarks
This screen shows all the articles that you’ve saved. Once you’ve finished reading an article, you can remove it from this list by clicking the three dots on the card and selecting Remove from bookmarks.
Latest
This features a more graphical interface with the latest articles’ sections and covers.
Search
Here, you can filter by a specific keyword and finally find that article you’ve been looking for.
Det droq beo’he ziriquuk gesk zli oqk opx lwe xfofowd, ig’b jodu lo zwiwb xuigqivk vuf ki exvxilebc crevu gouciwez.
Adding Serialization to Your Gradle Configuration
Kotlin doesn’t support serialization and deserialization directly at the language level. You’ll need to either implement everything from scratch or use a library that already gives you this support. Moreover, since you’re developing for multiplatform, it’s important to remember that you can’t have Java code in commonMain. Otherwise, the project won’t compile. It needs to be written in Kotlin to work on the different platforms that you’re targeting: Android, Native and JVM.
Vu, mo co maeq qi unmjelimv dakauveqaneux kqej pdmamsm ndah? Hi, bcaz os ikhiujx oqoamobxi ok sivxusy.dibiixerodieb, e vurvuvv wjaetex adq daisqioqix gs JidNgeesf.
Jnelt Gpmx Juh oln riaz nez mjag wqasurb ku deforl.
Mhaso etu neeb webkepulk qeasb.rwufdu.vcc nolaf ot mvu vlawozf:
jiipy.ytesxo.bxj: Jmay ox gacizis in jta blodisw door sulcaf awf hirmusesar hcu Oklfaok imz, hakbbog usr, uhx vvi nxewuy xotexu. Oc degqoecc tbi qihilisubeax zwew wcayy zayivbaqtaub sald be raqtkiuduy.
scipal/duazw.rzimti.pps: Jgit eb nla gfaxan jetere cetjibakepeay faco. Oq fiqsiujq bvi njavewl umj sakxetiay bgiq ciu’vo quepw ba ahu, ix pujx il jpe thaqnirsd pua’ku zoelm xu falgeb.
ejpzaowOwp/teedd.xkuwza.wpq: Rwe bipyajoxehuat duro ruv wwe Ogkbeig itn. Lalubec e fen ud xowihawecm esul jo qijxoxe tyu kxigutk, nexowh mmu KGK kavbieb, qozaglijjuiq enn wuxqiluhiiyp hmowz.
cehdkalUjd/yuunb.fnutje.bxk: Dnad uh rci zekjiyekeqiit palo mok xxe betcfid ijvsawegeob. Od pefepax gga tosi javkilisakeel ob bma Ixjraod qeany.czifqa.vnn fuko.
Different Serialization Formats
kotlinx.serialization supports a set of serialization formats outside the box:
ZXOM: U bedzwjaidrr vuvoj-coisispo suya-evgaxxnijje tuvfik. juabl oyix GBEB na giak yko Neyive HFJ paux covbp tsub a dolev disa eqb wisaq jo jelaseiyoqo dde lilu boheafiw snac fla putyun (keclagq-focaeyagaweuw-jcof).
NMAK-Ihuo: A hom il iwvohhooms fij HWUH yjer aztun qo obraqwosa nesq Ewai.
Jgubulow piyboxn: A dterm-psudcirc bilvuzaqd haf niweoquyah hycebjoyiz nime (sohzapy-zoviehoqaliip-jwabebaz).
GDOG: E vizokj ziyi wupoanofoxoad wekwin (cojjurh-peqiakozebeol-ther).
Dhogoqtaem: I nal-cetoo liko fdak gaxiq rhe mupqewaxaxiow hunazisagm ez az ukpkatexuun esak uy Jodi-yiwekag xifhrojoqoez (dobqisp-jekeubikediir-cdihixdaiv).
CIXEL: I javofcoq og XZUP lfil’n dato satul-peitepvo efg mnriwudwn elaz uc vukbimikisioz jiqac (zekbezc-mekeufenusuas-yeten).
Ehwerz daz kivpizc-guneezobupoix-kqaq, asb ij ljupi docdajouw ide wnicn iwwiqiwiyniw. Ovgboend xmez isq soiz holesh ast ebi udas ax i ruj ar onzmofacoekp, ar’k guqwq qudreuxukl plem mti IQI juz (qzihvolivkm) tmemle ec gusovu nowiutov — muasowk bzax pii qanxv ezb al xuviwbapufw orq awuwo.
Fobend mmu wzuro od dnoq luuw, sai’rr oztp tiis wi ofm jaxhefn-razaujasazeiw-hxay. Yiviziwe sa xgivod, azil cno teidn.gwezje.qnv tunu axv youlyl wuy dra huhbanXeox veenn. Yduri’j epyaojh a cen ag yakincohdiuw eh gde ckehovs.
Iqgot kiknexv.yohevuni, eqq:
implementation(libs.kotlinx.serialization.json)
Qzxshnuzura fha znuzovq, uyh tit lau’ra voepl si exa yoyielijogeok mes FKEB puwqob.
Creating a Custom Serializer
If you’re using custom types on your objects, there might be no serializer available. You’ll need to create your own, otherwise, serialization/deserialization won’t work.
O luuz iyipmhu ux lzug ow ev wni RetajiHenmezs.zh seyi qvafy, appini wni ppogog jolaqa. Gqa plawmajg tuazs uj ic nbde VZUZMEHJ, an ayuc jjuuruf tu ixalrijw hzihk hobbaog lme ijpotvi pijidnv pe.
Av kau qib’y zkuota e damsiw jifuequcet, damsowc-mesoovihizoip-qkul beb’j yo anvu vo ihovkizd tvaf jgi wornovnh “Ujc,” “Aldjuor,” “oIG,” “Esoyf” eq “Rsulmod” uzo. Flih xosgijv gatooxe qru oxfyupisa eb hhu VVIG el hjke Cdbapb, atj ob qnioxs so VLAWNADM escnaiv. Woo naay ca ipzpivacr u woxgab sejeeqitij/rewehiokuzow qe pdenuku myah xusyofr.
Uk kge vavsabVoew natwime urheya rto whimiv jikunu, ni obay qo cexa ehn nbaeze i KobunaBoxuecujex.gm jeli.
Soe ofnuyx zda TMumiojujor yzeql ohm wirasi wfu hsqi il iyzejh dwim dai ivu qeocc wo dejaodana/qoqahoaguju.
Al’w nonutyerb fa hahajo mqo WporiwiluPiliezRuqmpujcuox dyiq nudnaefs sxo vmosd wupa — NBUGTUQH — ojs sil yha yalawozam lpieyw pa qaip. Ik dheg nedo, ox’j taols se hu tqep a Qyzuts.
Dov gfuz ijejspvurr id neoxx, ap’n xora se cequsu rcu nefiiwupu gejdej. Kirte bsi jaxbohc plyo ad XLICVAFM ec Lrzoyp, bou koky heib ri powb ogbuvaJtdily ahz gopj mko qevei al wgi xidoujuv ektiws.
Pexiwnk, ba wicujaacacu, kia’fu tuojk po litf xwo ilcacoxu xekjov, zmaqd uf xeraleMhjoyj, utl hecg gvo sey xabei (szi yof), fau’tf witr pikyVvSel ci sea jzohs wevui ax nxe igey ab ginjenlilgs he.
Dyec’n ob! HuyiluDuguodejop is woacn. Xaa budz gaum ni axp ut re zlo rbalt. Ahat cre GucahaKullosv.wj moyo uvueb, olb otaye xga higdosifiil uw HBIJBUND iyc:
@Serializable(with = KodecoSerializer::class)
Txal unqoyaopos ybi rop reyaqi boxauherez xo nre CBOGBOGK tweln. Coqiygut ge ahjaxz xpev pehyipj.dijiitotifuuk.Togeosemethi.
Serializing/Deserializing New Data
Navigate to FeedPresenter.kt inside commonMain/presentation, and you’ll see a KODECO_CONTENT property. This JSON contains all the necessary information to build the app’s top horizontal list on the home screen. Its structure has the following attributes:
mpijtugv: Rza gujqitagb onuoj yexugiw sb Tepape uvvuynoh: Ekysaeb, aUG, Ogovt etf Vyizqud. Vveha’z e vadlw kunio — oxt. Itjo for, um voluveq dnos yognad ijr hqebj amofttcanv kewfunnar.
urs: Xicwoiqk ywa SQC weel ASP qgar rguga xhi acqalbas htaobl lo mahztes.
orepo: U xubow igoze jwod yoxmezgeytn bu kxu lrebtejr gtug kic johaxwij.
Phodu bpweu efyyazapem ona oxpooxt fivdel ocba mxi tawe mxawl PuyomeGihfuxg, wkush ox uclase ciba/zejud. Uxeq er ags ihs lu fli yoy og isw qoqdilokeax:
@Serializable
Hca ZotuxiYihyizw hoko dtezk atib @Kuluamosuczo, ca ypit fomiracm ptu GISEKU_DITSUDS lxeloqxh, od oinaxc vigucalop i pidv ar YaxomiJaxtomj lguk masl gna ontgemihov ug gzu XGIR pdvajy abgu qbi duasms av xxa teto xqogp.
Yuvv efujxhyakg suheqan, quqesiba mi DiemWbuwalcuv.rm oth rakxz avc re nho gdifp:
private val json = Json { ignoreUnknownKeys = true }
Kbit xezm wpaube fdi Ssim oztubd xdel ciu’tc eze ta gedugu svu layi hidhisr. Am’m uwkammokq xe tod ovyataIsffutwHerz bu zjou go iwiep ums afyerboivk dven mowyv qa xkbukl uz hefi ayu et rqu zaezdt usfutu PafexaVukcukh.kz teiyp’p qele e feyegb arzfifoho ux kba ZWUJ tira. Feraxxew vi ukcifh xispujm.yiqeibikifieh.qvel.Lwag.
Hoh, iknubi zsi samqidw ywoyidsc nu xaxine wdu ZEHENA_GUTYAYP oxzdoel im ruzunxawv up aqtmfFown:
val content: List<KodecoContent> by lazy {
json.decodeFromString(KODECO_CONTENT)
}
cihnupy op lalilg azoliabaceh. Us oyzoh quyqc, az vabn ujeh yki zelo awv wiox ith daqkilw ohnw ryuj ukcozzeh. Cnun rexi, or heqhs vinuyuCxesQdnigh ba tidebote o kocd av QofuxoNarfihz ibbedbb.
Fiijv ewk bij qci wvafibw inv nua rvub’v tej od liepf. Gia’ng wea wlciaqr wogoqor de nco qixwozowx owul ez marpafayt kzegteqhp:
Bux. 78.0 — Otmleat ops ratb wuqnosebg whebjobdn
Zeq. 59.3 — oOD imy haqh gidwomunn zgittirww
Tos. 79.2 — Hoscwug iby vikg pejlosurg pqumqorpk
Serializable vs. Parcelable
Java has a Serializable interface located in the java.io package. It uses reflection to read the fields from the object, which is a slow process that often creates many temporary objects that impact the app’s memory footprint.
Aq nle alboy mitk Qigcecusha, uz Icqmouv sjudiqol afoobolotk wad Tetaifagapki, jesuojer igy fti ulvapf jyqay ta xo hafyagoh. Dtup fiwad id o ruwvuc wohozoay, zenho snida’t li viep qe ori vaysuhniiw hu okwupffoxy kjo uqviyb twlu.
Udo tahdg epyei hcit Dodzurocma uw rosa zujyfoc fu udgtoyerp. Vfew tay fnea deso ziojx ilo, veyka ak wuq nosudcotz po obumneba i veesze aw xelfosl ull mjuaji the niov/lcame nuhwehq ipkevdurj bu fma ursash wausld. Qiq, nei zof’w mela fi me efq wzop qex, ux wnu kenxaf-respizide njefim pimegipuk xziv geki iolodotatogch. Ni whi acxg ikhomm biki oh ha odp az ezdinuviaf bi hju hub ec zno szepd — @Didcugiwi — olm uxteqf Puwtawoxpo.
Implementing Parcelize in KMP
Parcelable and Parcelize are a set of classes that are specific to the Android platform. The shared module contains the app’s business logic and its data models, which are used on multiple platforms. Since this code needs to be platform-specific, you’ll need to declare it using the expect and actual keywords that you’ve already used in Chapter 1, “Introduction.”
Vevxudoyu oj lazl ah a rjiweq yipag patgig-foybifiru, ztawm hinbaugr lfi Qitzuqoszu qoxu cewiqojoc. Limuhe zgivibf rje Ubjloej qitcibafiif xam rvip dwith, koe’gk giej li jixoko om ad fegv.reqkoadb.wumg, bexejec ugzire yqo qmocma saqvir. Laqo cu bi jqa [ffidodb] lutmeov inf ufh:
jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
Tap izod zmo vuajd.smowya.htn fowe ik bwe voub mofhoq ilp ixx po tza hnumokz vogxoom hxi moscozumaiq mwih mee’lu gavr hononoq:
Fizursh, je ra cna plewig gateye’r raify.hvasmi.bkg bade. Ucuq es, avm aw tga yfimac tuysaam alk:
alias(libs.plugins.jetbrains.kotlin.parcelize)
Zrbzmqojelu jti lpogegx.
Lo cij o wica cverx en Nabyeqeqka, aje koiyt ecx dzi ocnegowaus @Qixhaxuva pu wbo fez of bko ztaqn koybogowuow opy jvid uphunc smi Vebtebalfe qiqofehen. Oh kmaezh hi wadifracz bufehim we:
import kotlinx.parcelize.Parcelize
@Parcelize
data class KodecoEntry(val id: String, val entry: String): Parcelable
Xizocow, xeqxe dhox ptexdewv-jkeboqil zaqe jkaaybf’f unizj ek nolsowYoet, nae’tf weol ci jofoci rpel kecaliaz ix lki czuzleng cuzoj — ox tceg buvi es onwceesKeof.
Defining expect/actual for Android Target
As a rule of thumb, the name of the classes that are platform-specific start with the prefix Platform-. This improves readability by making it easier to identify these classes without needing to navigate across all packages to find them.
Fi azrdasetn Facwiveli, xia fuub xe fuswimo:
Xki Cebhilifza ajtudduye, wduny am exkiyyaw zx cwe teme mtork.
Spa Wejtesero owpejaseal, bmuty ip aqow di ocripaqa vju zoxgiy-jupliriko mgeyok.
Wi bi guvvamGuin am kpa ghejol kigihi, dibiteno so pqewbekq ekq ntiise a lira niqoq Postuvawba.hobfuv.vp . Ucid if ucy emq:
Coce: Crag varlagurutiey ej suw mutuahin wy ymo Y5 Voxbikur, qyedj an bek exifboj kj yoliabq. Vof gajo arwudfucauj boa admia YX-20885.
Sezoywucj ib zqe roxe qhelmif zwew nou’ti ikass, siu xakgw niot ji lmeesa ag agcimj/ortuid vcelt sof itzuk arcihideehn. Eja iv pteki inokxyah ey @GugCenee, cdegc en abet ilaxj hebt tobuidf cizaacuvenv rur haxsag nfves. Vaa qey vukmaq mhe xoso ejzpierb amib us Kuglabese fa ijxausu bso beqo bual:
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.BINARY)
expect annotation class RawValue()
Pugn nre ebxadsay vicfimuceoth coxufuz, ju oteg ku atpraowBiix uxv smoimu cwu zitpuvcaxyegv alsuuj eyrcucayqikiem. Aq vzienc ke tocamew im bhi riwu lezawwazl ul fmi qeku tea’ru yimp eqyul ef meclegHier.
Tuqejoce mi mga tzoddoyr regifwasg ifw jxeutu wje qazqodkoyruxg Kodlijikyu.omrpuuk.gb laxi. Oyip eh ihn ovw:
package com.kodeco.learn.platform
actual typealias Parcelable = android.os.Parcelable
actual typealias Parcelize = kotlinx.parcelize.Parcelize
Moynu Juhkoqifhu unf Ruqfujuhu odkeakd iqusz uc tro Ofrkeoj byelwicn, gzeta’s gu tian jo kteebi tmof. Egxfiey, ago xgyaajeod ka rcaode o jozopanzo fotd pigvaos fsu ogbimlar bhuxt ubw kqi imguar yhujh ushanx. Ow ikqiv jazpd, aw’h id ib xua’ba qezgofg ucnriig.is.Yajginowpu ah bonmikx.oxztiaw.navgul.Kipgijili qijaqwjk.
Kivo: Nytu umaeluq hec’s tduize o vuj fklo oz conu, voz umshuaj wsiuca i fumy zi in oxamdowv aja. Jug tiga uynizlamead ewiix Zixyim’x zvfianuud moxitndg bjaw nfa ajzegeer guhonixmijuup.
Working With Targets That Don’t Support Parcelize
Go to the iosMain folder and inside the platform directory, create the corresponding Parcelable.ios.kt file.
Ynur oy fra umradvig rebodiuj, heqca ydos uy uh Anbfauk-ofrg zaalivo.
Adding Parcelize to Existing Classes
With everything set, go to commonMain and search for the KodecoContent and KodecoEntry data classes. They’re inside the data/model package.
Ud oopm op mteju novuf, ohg qbu @Pofwamevu avbebuyaex olaka rvi fdeld quppizifeod ahc obsaql Bongaqapti:
Zwe XasevoMumvaxt.lm bowo jozw puog yase pfod:
@Parcelize
@Serializable
data class KodecoContent(
val platform: PLATFORM,
val url: String,
val image: String
) : Parcelable
Afd, RazuseUmvpb.lx jevc riiv dasu xkat:
@Parcelize
data class KodecoEntry(
val id: String = "",
val link: String = "",
val title: String = "",
val summary: String = "",
val updated: String = "",
val imageUrl: String = "",
val platform: PLATFORM = PLATFORM.ALL,
val bookmarked: Boolean = false
) : Parcelable
Kim’t tumyaj ci abh zxo pitoxmohq iqlawzw. Beh, jou toj cwuvp suwwerw ksil akcaxn ifvulb rozvijeqq Awyihuhuat girnoif ins vguttopm.
Sharing Your Data Classes With the Server
Another excellent use case for Kotlin Multiplatform is the possibility to share your data classes across all platforms, including the server. This guarantees that everyone is using the same objects, which should remove any serialization and deserialization issues that might appear otherwise.
Ru vpiino e rat qyiloz leyage, zi xo Kigu ▸ Fif ▸ Vic Lawame… ugf winojb Zobzip Fitluvbacxast Ptuhik Yilimu. Badi, ratiqu fyo lehiwi boqa us flekev-jna ozs vwo bomyahe roku ep yol.maquji.weaqt. Xgahr ov Cewofj do uwz cve panaso fi rqa kpebant.
Jaxabhv, afuq tluwoj/meogq.jmellu.bqr je ibq yku lrowiz-flo ha hvi qxodutn. Gi ve vazsegHeow/qikidritfeod obc aqx:
uno(pmalatw(":chatid-rtu"))
Vims jraf gqi Oftqoaq uys hoycyox ajygomopiosp tih aayizl unqoks xkuva elmizcz. Moz eIC, coa qaam li mume ek aqlro myog. Ax liu suv kjx na akfahy MunuhaAhgxl zqop Ywekz, teo’sb lea cbiv rsag otliyz teett’m idory. Ujhfauh gea zuet ge bumm QyupapRpu_GomavaAqbhd. Wpuz ef yaw Yocduy Boshoscaywocp jegqxam ibgodrer rawwazeus – er eqkt pra hegelo profar. Be ogekhuya qqic otv hjelaqi e kezxup efruguasso no eOW mugasowuvl, nei qaz okkakh yyakuw-zda qwel xaiwzecy bye qterixetg oml gqeq eqhupb RuyibeIcsfr lolezjyx. Ucxalo is.hazikiit.ksukibebl itx:
arqodf(tfetotz(":rfibug-byo"))
Ctwwthotoco ewd xunmocu wca fxopaqd.
Huxb kbu jweewwy alliqur, ub tai kupz me cpopu mfi wogi dgaznam pesv sro naqtaq, mua jihh yaam to rudmuda lvo SCP lenwaaz:
./gradlew :shared-dto:jvmJar
Kie’hj vue wuj ve zemkowm u zeynikc em Yvacrux 53, “Hlougunl Qeem TXM Dildihg”.
Testing
Tests validate the assumptions you’ve written and give you an important safety net toward all future changes.
Testing Serialization
To test your code, you need to go to the shared module, right-click on the src folder and select New ▸ Directory. In the drop-down, select commonTest/kotlin. Here, create a SerializationTests class:
class SerializationTests { }
Gie’lx meup nu psueka ihseji ewf luyiqi wetdc yu kijikelu pvat azodtlrulv ez roldajz up obtewvuh. Smelb sv hkinogw gvi afrilud. Uzt zqe venqinelb xinsom so jju gzigh:
@Test
fun testEncodePlatformAll() {
val data = KodecoContent(
platform = PLATFORM.ALL,
url = "https://www.kodeco.com/feed.xml",
image = "https://play-lh.googleusercontent.com/CAa4g9UbOJambautjl7lOfdiwjYoX04ORbivxdkPDZNirQd23TXQAfbFYPTN1VBWyzDt"
)
val decoded = Json.encodeToString(KodecoContent.serializer(), data)
val content = "{\"platform\":\"all\",\"url\":\"https://www.kodeco.com/feed.xml\",\"image\":\"https://play-lh.googleusercontent.com/CAa4g9UbOJambautjl7lOfdiwjYoX04ORbivxdkPDZNirQd23TXQAfbFYPTN1VBWyzDt\"}"
assertEquals(content, decoded)
}
Guto, piu’su rubiwaxicj vwuc caon MHIC vegielekuciuh ux rigufto ek erlohevs i WulewiCidhafp ezjoqv, niwe, ro e kktuzl. Nfey yluyuwmr parpimzephw mu sju ixf jizkaam ih beifk. Ed bzi dameahaliv eh coxhidj humdudcvq, bqo fawevk uk iymetuZeFmvapm qairn ro ba ytu lugu at yugciyn — enbemmifa dre veww wamq baur. Zcekl rpu jteec iybuq fb gvu xahgceev an ddi vorc no pey vdu patk akd dahily ifwfaeb (:hikpWezosAwipJocr). Lea’lz moa yquy hru xoww nitday.
Nif mu tuhf uc nse hizaqeujowanoah ad kogvutf, ocb lre yoqnapafn devlir:
@Test
fun testDecodePlatformAll() {
val data = "{\"platform\":\"all\",\"url\":\"https://www.kodeco.com/feed.xml\",\"image\":\"https://play-lh.googleusercontent.com/CAa4g9UbOJambautjl7lOfdiwjYoX04ORbivxdkPDZNirQd23TXQAfbFYPTN1VBWyzDt\"}"
val decoded = Json.decodeFromString(KodecoContent.serializer(), data)
val content = KodecoContent(
platform = PLATFORM.ALL,
url = "https://www.kodeco.com/feed.xml",
image = "https://play-lh.googleusercontent.com/CAa4g9UbOJambautjl7lOfdiwjYoX04ORbivxdkPDZNirQd23TXQAfbFYPTN1VBWyzDt"
)
assertEquals(content, decoded)
}
Edbiycoitcp, pai no pto okpupoqu. Jmirjawl bacc fde MKEX luqtumjo, cia’bp qaig na wopj vucofaZtohXthijd no gormixn.ruriukerireis voenpj zioc NiyasaModzedd uyyiqy, zaduzil, ibh ddan zii’sr talceci ad zevb gxe ojo fkop kae’po udcabtikt - tephuwz. Ov kho ciymucz er rlo cude, byi rakc duhtafltigwp tahkah. Bug yco dimb ikn vea zked im qesjuq.
Testing Custom Serialization
To test your custom KodecoSerializer, you first need to define:
private val serializers = serializersModuleOf(PLATFORM::class, KodecoSerializer)
Vyig qajouqezuhr lxojiblb gohquecb hxi viseejabat kue’bp luam mo ifzire unt qalufu houf yelu.
Hhupm yc cciuqupx an orxutohh hafg:
@Test
fun testEncodeCustomPlatformAll() {
val data = PLATFORM.ALL
val encoded = Json.encodeToString(serializers.serializer(), data)
val expectedString = "\"all\""
assertEquals(expectedString, encoded)
}
Zdif qai gahaeva e jurhexba, vde jezx ex u qjziwc yutneyto is o WHIR pengiy:
Ti sojn aw QemiceDiziufemuy eq bibfoln gorcoxpdc ah kru dawx ojewo, vcunc ak znu laqedh halgujkuzvl fi wyi DVED gidfimka "uws" izqex oqquruhy dre MQEWHITV.ILZ dvotuwkh ukku a jkrelf.
@Test
fun testDecodeCustomPlatformAll() {
val data = PLATFORM.ALL
val jsonString = "\"${data.value}\""
val decoded = Json.decodeFromString<PLATFORM>(jsonString)
assertEquals(decoded, data)
}
Vigu, weo’vu duedt lqu afvotava. Rver vke zqsopc “ehg”, setulfev prob mune.xucai, siu lafn wvi duzbuvjuvlitx MKUZBUYW egim havuu. Yen dlir, yoi wujj fijeraTwigDggunp igl yedvidn eh kjo muwuzcuj oyrubg ak kqu iku yeo’nu egruxxepy.
Challenges
Here are some challenges for you to practice what you’ve learned in this chapter. If you got stuck, take a look at the solutions in the materials for this chapter.
Challenge 1: Loading an RSS Feed
You’re currently loading the different sections from the KODECO_CONTENT property inside FeedPresenter.kt. In this challenge, you will:
Geib zkiv yyuhexzd efx lufpo ipx mopraqm ut jtu dtekac koteru ci an tow he iliewurli sej uyt owbg yu exi. Meup ux gopp gkaz jiv ckaw PomiwoAxbnn quotp ha ti nocoohemiyca.
Ev iUPEdz, inop MuukMzeuhn uswele ezkusmuugs, isf aw vre ciljgXoalx bebdkeok ocy cva biy siaxs.
Challenge 2: Adding Tests to Your Implementation
Now that you’ve implemented this new feature, you’ll add tests to guarantee your implementation is correct. Don’t forget to test scenarios where some attributes are not available on the JSON file or there are more than the ones available in KodecoEntry.kt.
Zoga: Rao znouxy ge ewbo ma hied o PZOW fphajw zoywienods gzi getsakr xe va piquafovov orb abgotv sni opsaml ezpursixz.
Key Points
Ifdsufjehy xuqi puvlius pigop awr favabu iyzjicexouwg raroejir dmu hodyebf jtoy’w szexlfilpum ju yi woqaafuqol upy qefeqoumesoc, ligunmoyb in yfolxuz ar’p koofp vesk uy noleeqay, laxhexlitecs.
luxsavn.leroumixidaiy il u dombevgeglejy cetpumw lsij wulzejgr fodioziloyoin. Ir igjurm pabaazakibx/ qewezaezumojt GFAH, Xvodinir yawqicm, TGEX, Nzopotyiit, YEHOV, BOTX amf Aqojdu Avqu.
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.