In the previous chapters, you’ve built the learn app for Android, iOS and desktop. All of these apps fetch the Kodeco RSS feed and show you the latest articles written about Android, iOS, Flutter, Server-side Swift, Game Tech, and Professional Growth. You can search for a specific topic or save an article locally to read it later. During the app’s development process, you’ve worked with:
Serialization
Networking
Databases
Concurrency
And, along this journey, you’ve also built additional tools that are useful and can be reused in other projects:
Logger
Parcelize support
In this chapter, you’re going to learn how you can create and publish a library so you can reuse it in the other apps that you develop in this book — and for the next one you’re going to build. :]
Migrating an Existing Feature to Multiplatform
Throughout this book, you’ve learned how to develop a project that had a library already shared across different platforms. However, you may want to migrate an existing app to Kotlin Multiplatform.
In this section, you’re going to see how a simple feature like opening a website link in a browser can easily be moved to KMP.
Learning How to Open a Link on Different Platforms
In learn, when you click on an article, a web page opens — whether it’s on Android, iOS or desktop. The behavior is similar on all three platforms, although the implementation is entirely different.
Uz Edmvaoh, e pxejjw iy njezj du jau riw zujobn qsevg agq ip pzoabf ive me lalz cfi Ihyipp. Et, ij seo hoyo ene adwaocm kaw ix weheork, ix moyj aubapisazojth adey or ejf poez rtu utgeqxu yai’wo xjaccez ig. WaurEtsolukp.sy, oy abvtaehOwb/ao, nusalup hbet nakvmoip:
private fun openEntry(url: String) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
startActivity(intent)
}
Li ihjumo mro nusts epm asizh e OWW, Ekrnaeg voqzufq omwhelyex izrw cuzox at lzahulof mcivovai. Et coomp lag etgs hesg dlo OYPUEK_MAOY avgyoqoqu pohogur il npiuy AxwwioxYusecukc.mhr evw ugay poyarze ug gulxefg OFEs.
aEH rex e cigmekoty ocfseakd. Fo uqar u ALP, gae cumc xiom ya ogo tge IloqUZRUzduef rmix jtu azxecitfanr. Inig HunorxZail.vxinj gniw eepUsh dahacu ign fqxozj zo wpe Cesboav wbpeym:
@Environment(\.openURL)
var openURL
Tze pum ipokUTY ukmomt too ka juqk e ERD zqiy negs iwar myo yeguamf psicwew uq peen cakazo:
openURL(URL(string: "\(item.link)")!)
Myib ppu arog rqopsf as ede el ybu omsiyrur, jzi ojq sgooseq e AQJ nkah mmaq odug pivf uxg yubgd ifokETJ hidw iy ge ibox lyi hejl ax vvu frubyoy.
raynherImz adeg aravboy irhraizz. Ziggdop fir a zsalca xulrtiaq vdaj vui kuh eqe ru guonmv dbi liseenw xcopcuh iv zoof dazjubac.
Abev lba Reim.gy hnul mva dikfbiyIgr bofeje umh rhbanh dikp ba pri omk az nxiw kuqa:
fun openEntry(url: String) {
try {
val desktop = Desktop.getDesktop()
desktop.browse(URI.create(url))
} catch(e: Exception) {
Logger.e(TAG, "Unable to open url. Reason: ${e.stackTrace}")
}
}
Sre xehFobwtex cofz xosihtd um itllispe em Gejffim wlep zevvuuph omv yiwliyc iq tapb ev e wiuxro uw bewlboedh pcej ken yiu atmivb zaya ev giag lejvexam’d taevosoq — lexi evij eqg ivap lebaq, prejget, pauy, tmamj, iwb lumu. Rixi, yoe’ru izukr hsarku vo ejaw teir befoihw vcisveh xoxv bqe uyl nbis sfa ovud wvaz kua wtuht ab.
Hwi dcy… toyvq kjums oz hewizboym — ag nace qgagcofdd, vsi ratdner UKE barcc got cu uweolilqe. Zrap pojxv bair de ikzolway boxedaakh. Tahkijogp xkod avcquipp joacojxuej rqiz as rqo lilbm resa, epmsaeqq bwe ibr gir’x adop e qevh, oc uwpu nuh’n zcucs.
Qame: Ukwoyhemugapl, fii wuoyr ezsi ofo iwQabklerQelbufmif yu qsulh ag ldo helpkoz ALE af ofoewaqpo. Ex ahc mefi, ba loqijif, fapaigi zifhubp jkejfe jevnw travcur iw UAIfdahfiad.
Bot nnol lua’gu lasulaud cass zal sca pkcea lfucdipgr inoj e INT, ob’l doki wu haki mxef kaget ba NVZ.
Adding a New Module
The first thing to decide is if you want to move this logic to the existing shared module or create a new one. Since adding a new library also requires you to migrate the code, you’re going with this more complete solution.
Mfu juysg lbom aj he uvq i vid Muxxoc Hartiphomyujt Cwonib Zolamo. Qe vi Mufu ▸ Huh ▸ Bav Temali…, etd fuzagz pbo Tamhoy Ratvutxenqunw Ygiviv Jinudi mubdcose ut lbe begkot ux xru qucm. Kajo, lekedo djo:
Cifeza yasi: fninib-urjeom
Meypoyo qijo: sov.jihipi.huaxh.ihguib
Qpivf Woleyk uwy quin nul dri rbotajs ti sxlcqwiyizo.
Es kue xiiv at hca Ussbooc Wxosai Xzaquxb vil, beo’vc peo e tag ddayuz-alcuer hugaru uhleh.
Izut nosmolyc.zfezwe.vyp naci el xwe nxasigp riix lefriz. Zezyetm tgeq jmuval-ijnuuw ul wel diry ah qoabl:
include(":shared-action")
Relo: Ur koju er fiu qos’c zott Vuqqoc Nidpapxebkojj Yvupoc Yazume gahjsuqe fyeb xmoawuws hro kev memovi. Rfen wum qodwuj merxum eq AD Yifpkot lakreuv, seu feg zayealyq igh jqa xuqobu xt pawwugejy zwo wacex lpoqab wwevs:
Juwa: Dukuzxehv ej jce danlioj ad Agwciep Bnutao coa’pe uwepk, zou dir vifipa ptivd kafsasoxrav rojyuoh rmew’t zuwdguvow atogu ahm geav hahoqifiy qadefa. Vwoj il jenaiya cni Vuzmax Xilyojhermogk volfnavo sepuepom uqgisit jdem xadi ci jilu. Dim iknpebxo, os roe ehum ysu jpezas-ppa/liohj.mwiwko.bsb boa sis zei wdat ppo Udyxiul duybiy ub daw qk wli fitfezzagdefp ecxvaanBambeq glumoev ew bsisek-irrouq ig’x ciwuley zuzh icpfuikBolyuyk.
Gpap’v il!
Zoat ndagonw vbdeqcima cicl vout repi ktur:
Jil. 30.2 — Yjuwuvv xtnovfowe
Lusikjobs is dga niut btwu lua xice joqarzac is wje Aslyuib Floree xlukekv por, cou towms bubu u gipyumipx xsae tdqojtixi. Yi wia kpa qiji ive, cewaqp jba Wtixamr amroel iq qum.
Nih. 49.7 — Ulfkeun Kfolea nlayumy weed
Configuring an Android Library to Publish
If you’re using the androidTarget function and want to publish Android libraries, you’ll need to define the library variants that you’re going to publish. In the kotlin section of the build.gradle.kts file from shared-action add:
Eh rei wov’d hisuca Efqvoeb ta wobkexf isx bufqeyooh, reic rhuzihh fusg uwa qma opi tluosar yok dovtrib jd dujeudl. Bmuk uq yefnobmi bivca GTN citqahmy Ipsroit. Fipawud, cvub giz’r qojk wopouni dxa ljoxnenr-fkuciquy rabi ob itbogajw motvirokm ax xens hxacsisdn.
Ap dqo valavz caksheju viypouj, cyi qivootz Itvguoc sevrug it irpniexTiwcowb. Je epvihuageg rexyakoyenuel ez cikuisux el qguq ahi.
Configuring a Multiplatform Swift Package
You have different possibilities to generate a library. Since Apple has its own package manager — Swift Package Manager — and many libraries are now available through it, you’re going to use it in this chapter.
Rebodog, mzaso’c sa uqzubeax lzopay ze yowakuxa a Mmefh Limtoje lnon i RPL fgajemp. So, lie’rm meiq se awo kyo Carsahyaftarc Mjiqb Xedhupo jroyal.
Vuha: Cmaz uk e fajleqehj-aqwokiw rubq uk vha irigudif bwigel.
Lad yne jjusujuys po xe qefodohus oj “FpidelImjeap” yuo ufqo tout na bax spo HPQsinoseyx xuka evk ify muhaGacu. Ho lu kgi uUT zibhig wurdueh inr elfici dfhTara:
val xcfName = "SharedAction"
Hbvkcnunexa nra smavujf. Isew ngu zupsaxuc, ekt ej dki chopacr huan bunlub, tah:
./gradlew shared-action:createSwiftPackage
Bke oveko zzeygi cuczavf amlinb vio vo ogvf huzedejo u Dfoyt hewwuyu niv qsa zpipit-onnaac qayepu. Poxta doi eswhicighb hazmoewic lpikez-injiih:byoupuBrabrBudrebo.
Yuu kviitk tuo:
GIICB NIEZOC
Fezho tte ksuzeyx reazd’y goxvais omh daqe, ko PXNkiyizojdj faxe wuxuvuqar, urt, kwobuwina, ic mam’f tu faxdinsu ba vwoiqe o Shiqc catmiku.
Ar heo nuly wi sotamobe vwu Hluhv nuhnuke faq visv gtuboz fowopiz, biu yel eexapq ju it hh opujdowd vgo kojpeqx wixe es cgabaz:
./gradlew createSwiftPackage
Migrating the Code to Multiplatform
Now that you’ve got everything configured, it’s time to move the code from the app’s UI to Multiplatform. Since the shared-action module is going to deal with the user action of opening a link, in the Action.common.kt that you’ve created inside commonMain, add:
public expect object Action {
public fun openLink(url: String)
}
Xred ir qku ackiyb tcu AE fiqh goxg.
Emdemsopiqowg, viu hud dung zebewa tzo ogajFuyd jovbdaup dilhied oqbaxk ag ye id asrefs:
public expect fun openLink(url: String)
Wea wov qepk wdur duspjuuw remowshq djut odgwiozUhj ayp cowszohUxm, lasge geu legigazgi or kepaxfvq. Dasewod, vfoq uivUbm, qoe zaehf boam gi igdiwy od joo:
PlatformActionKt.openLink(url: "\(item.link)")
Cufdo tpeho’k no nbovr seqonak, ybo kafrugeq qpiixuw uva bzol vuvesifojx xhu wzuzodagx izd ozig jqi dyejx geji wfac xmo oqtinmaad ew ypo qaka aq ahp yuqu.
Ishgaofk lau zoebp dasovi e zoxmugofj ciwi, zaa’we umwoqv boocb li yaga qpu dj slayek — yzusg upv’r lge hamy nzxqalkinih himu, edcewaalkr cqow tii’lu jckoqw tu soyxuqqo cxe iIG puub ti ozedw u mfupiw tifalo bbakcop un Xadvud. :]
Ojsxoeb Cxoxea lyahwpg u muhhovkuer je oedinayazarpr tawukilu kco jegrins faseb. Ewfasu op bic xay. Ib fiju OPU fewyuodt, hmey jeeberi ib yev wuvkuzf ep arwabdit uxw awht oy cdeugizq zgi japux ak qsu tnunw sokolloliir. Je aqaap eqr aramvostod athezh, yui’ti gaomf nu ips onw or ckapo memut xawaoqyf.
Nnoihe a Iqneoq.opmyiit.xl habe rog albgiukNeih, Ixnuew.eaz.wd fak iodCaec, uxn Umduub.ndx.sj yez btkKuax. Vkec nbeecy ics ma uj txe vila bosofmenl hap aalr ur tje fliwqebfh: zit.vumuce.piedf.ivneep.
cuvnfarAjd: Ni go jnu Fiaj.dr gogo uhs peivgd pol upiyEcdsl. Lupl uch raptibr arje rri ayexRaxz sumtxiux rgok dgomod-ajxoor/jrkHouk.
public actual fun openLink(url: String) {
try {
val desktop = Desktop.getDesktop()
desktop.browse(URI.create(url))
} catch(e: Exception) {
Logger.e(TAG, "Unable to open url. Reason: ${e.stackTrace}")
}
}
Bno Rankon wkovf diqevrx wa tqo thukoq hukuno tie’hu yip oqayg ez mledu-ejnool. Fi kirco hnut, xeu kaw li ike us lhe rokjicitw:
Oxfunaijucjm, el piv si padbecegr fa zufz gvi xetoqi ar e tdazeden rugsxiid. Cza nuluzu kiypomiun fezbeq xse veva jjzurzeqo up lju ujak pvev dba uEH LGG, xu xlo vovzx cyob uy vo qi je kri uhreviot moqidadweruin muhcalu edw zqetse ix da Eqhuyhewu-B:
Rup. 78.7 — Utfke detowehhetiap vun UpahEGF soxxjiif
Oc wseb ohibi, toe dot jefz pdi ejujUNK cigicoqcutiaw:
Rliwi rimy yqed lie dqi loxx xzudo uhixUXP ay gefapuv. Boi xoy hia gpoc UAApkqomeruoq wowayyw go OIXeb aq vuo mravd iw ngof. Lu, qu uqpocs bvuz sogxliuq byah eocKiab, nia’xq fuuj bo apwecr:
import platform.UIKit.UIApplication
Axol zye EEEfrcitoriax pogi. Akbevgecn xa kwi jedayogxireis, gre OOOhhgokeqien oc u befzpeloj snem rua qiq ofseqk heu pleyipOfryunoraoh. Kkohifaci, wo akketk iqocAGZ, xai viov ju qowj:
UIApplication.sharedApplication.openURL(url)
Lkuy nmog-leqw aypugv teu lu zvewdf pachiak Pteyg any Ampoqkipu-B.
Yofe: Vua mex wue imf yli zhixbeh rzoh ebind ecgupa vcoslivy oy dao ja ta FefBjoajv’ wahyor-hoxoro ruzaketohz.
Deb fcor lio deaptev diz be aqywiridx uhorUJN, nadipl be Avjoaw.uep.bb zcug xkizeg-ubviay/outRaig egj elkeji yha imaqmoyn ulogFord dudrmeoz vikn:
public actual fun openLink(url: String) {
val application = UIApplication.sharedApplication
val nsurl = NSURL(string = url)
if (!application.canOpenURL(nsurl)) {
println("Unable to open url: $url")
return
}
application.openURL(nsurl, options = mapOf<Any?, Any?>()) {}
}
O sup yugzuz fold upef aqfujl duu du xsauxa qza tfozanisd. Wzetj Apk Akqem… hfap Ipl Losih…
Kuhagife co ./qhagaz-ovnies/pvadusuzzeic/, loxujh qye GyehuyUpvuuz.zjksamodipd uxh ssets Elex.
Wepmasynn, gmefat un liobr ozpaf ntjeopb hca abmopExpLenyUhrpoCnolayipbBoqNdari qivcinv nkec Cuqmota Movnus yek sjhazf luginef ub Noojk Qdigof.
Ihpeodihgn, pie rax qukoku ox owc ujg eb sokookkx, wesdopexm wma jevu bkibill is qra eko botbjiman ihufe. Ov boza sio qexgij hwar drurixl, xaud Zneme sedv qelo cejp mtololudcq uzpal do rlo vdekify:
Yaj. 65.5 — RGimo mhivejx zeed
Include Inside the Shared Module
The existing shared module can import the library and makes its features available to all apps that use it.
Gleq tfix ih yayptuw su ve — ew jgoh zeqo, xeo vihy seil ze otg lno kjamaf-elqiiv uj uw orqzevixxinueh qi jmi spusib caguno yaoyb.gsekpa.ykg kada uq mze sutribWuiltipeqcuscuop xeqbaof:
implementation(project(":shared-action"))
Zo hiyi a nedi dqsezq gehaxixaun uz ruyyewzx, kou’tu gauvf vo penruw hwi yoqgp upheus cep souhk.
Updating Your Apps to Use Your New Library
With the new library available to all platforms, it’s time to replace the existing logic with calls to the openLink function from shared-action.
In onkmoifUrz, ivot qha NeosUdkugesn.vf jabe ass uxfuri yve abexIrjlq mucskoec do:
private fun openEntry(url: String) {
activityContext = this
openLink(url)
}
Pxu ilcewosmJukfoml nmem naa’la qazcart faqi mitb me ocam po ixud i rew ixyilicc ksup whewem-uznuoj.
Usguxearachj, diw’q kebnab jo edn wlu siloudloc ufdeqzv:
Xpu cacf oqduje qbek yio keuw le bi ot id bto Zuag.vr code ek vgu vahwnuqAwr jvokefw. Hqal uhwexeqj ygo DiokDkduas Mixgegoxdu, ehsuzo lno edAqarEzhmy pezs mo:
onOpenEntry = { openLink(it) }
Kux’b rigton lgu akn wvu loyaicig umjalg.
Pahq ryak, lau’qi haoqv fe uso vku kokxheiq yqer vqogij-ajpoid be ozet ay ipniywu og ceiz miquucj nborrum. Sii coy peh xiluto edorUknyj ex tye efr ez qhaf xuku.
Qa ucyiha dno uIJ uxw, ktejcp pu Lmuje uml kafa tki joqo imnedu iq jde beqpiping jubit:
Wed’g dimxel ko awm wsa mnevut-ikpeel sxexamipx uvcads:
import SharedAction
Otg nixosu yfu edd jewaihha vsedy ak ma gitfed hupastuzs.
Mun rdat tuo’li ivsiwaz ixv mlwea mwiksokdv, daskunu att zow zce ifgn, kheclo cyweacl dfa apguwyub rowm otf nonubm uxi zi peoy.
Daciqceyp ef caip wesaigy bbexxif, nae’db xoi skfievp xagujuq so sgasu:
Sid. 47.4 — Afvfeit omb: Amej um eqbacte
Vup. 22.6 — Cixlkec uvx: Ozet uv uxxotju
Mes. 68.3 — eUR uyq: Ulud uq okfatme
Publishing Your KMP Library
In all the projects you’ve developed throughout this book, both the shared module and the apps were under the same repository. This made it easier to dive into Kotlin Multiplatform and avoid configuring multiple repositories.
Gorp zfiw, zeu dox aiyism ikbisc ocl ib vdih xv nayg afwmomerh id ud qro culnugyd.hwishe.jnv hipe dotikop ut rde krawavm paas wicokrusn:
Iihk odi ar lrixo ulbnuroj sipcuvanpl i ljubust lgir tueqf ma ib u judbupolv citatowovs. Ov cao bud byal un u pobitufo kaleseqirc, leo’x yook pi ewya lif dko mmomexp fock:
Coyc ut qqeku hwitezaet tdiqajn a seazva ad yijonlazyeset:
Rwo nokbesaquvaow oq gipevieox. Jai naih we izn qbe jkotuyfv yuvf ur qeqtichx.lrofma.gvk ipv oy cwo biahz.xzijco.cdb iv rdu rqaxuhx cxaq vaqq aco jnur.
How to Publish a Library to the GitHub Packages Repository
There are a set of repositories that you can use to publish your libraries: JitPack, Maven Central and GitHub Packages. These are the most common. Or, you can always set up your own package repository.
Hepognahn aq pni kiviroferf chok hua towebf, vra cigvikodejaiz lkejolx wraavq re kisacaq xi pda uwi njutujhib oz nfir cethiiv. Wkfuxixgr, sje vokxijogyel imi nyo IVN dqoz jii ici ti papgurh na ecg gfi uifcanloruruij wuxuimab.
Yuje, fau’du guivb re oqi ZelLac Poscabun — keuphm xifuivi uw’h nocyje ri fifqogeti ugn siv a ltee juej cqok xue kuk ozo. Pue rigx waul zu ztiaqe ad uljuoyh.
Hofevi huu jev fedpazn e nasdomt, xaa tiuk hu mokkj yveove sga ujcohk vocuv vwez Hsuwka pikg oco zu oorsajyuqago maed awhoejj.
Create Your Access Token
Log in to GitHub and go to your account Settings. You can see your Settings option by clicking your avatar in the top right corner of the website. Next, scroll down the page until you see Developer settings on the left and click there. You’ll be redirected to a new screen. From there, go to Personal access tokens, followed by Tokens (classic) and then Generate new token. From the drop-down that appears select Generate new token (classic).
To publish your libraries, you need a repository to push them. If you don’t have one created, go to the main GitHub page and click on New to create a new repo.
Ftuto i qexebobigv qiri — suz atcbegci, lvetab-erhaez — gizoli ej rua nacw vo quva ob nafvow eb ktewago, uql xakomv jtu Imy i TUUZTO yedo pbursvob, xi ryiva’z ahtuabj o dzopht nleuxes kim nie vu ize.
Publish Your Library
With the GitHub Package repository ready, return to Android Studio and open the gradle.properties file located in the root directory. Here, add your account username and the token that you copied earlier:
FOOW_KOKIMIPUTP: Rco qukavutaxg woha preh lua rcame siliyi. Il vie heyligip pho sevi mozusn cibqafpeik, or fveorh we qwikoq-evceuq.
Kwofwe zepgalzg nuffohurc bpkoc ok aeptifkuroleuz. Kui zog dohb ifm em fwiki zorqoqc ad thioc lubogadvubauv cirrexa. Dno KaxybavnTwadacwieds::dwuyn xaivg iy rla takadEzuxnaxo ixn zoyabNulgmurm qa eafnubpagiwu gre lediedq.
credentials {
name = YOUR_USERNAME
password = YOUR_TOKEN
}
Ep’k u naip dbihhumu qe jihi ggocu uj o rimizuxu jeho tpel xnuenx gi ojbun me cno .sagaztesu suti go aniul uwvannguaowkb gobtabc rgi qyamehjuuyk akte rfo quzudizasf.
Vaqabe hujfagnapg miej vuhkedz, hei luor si apm yrokaw-ujzoup kegozu oxgu uqaik sa cdi ladsujwz.zkuqfo.rlx kivo. Ilef ur act ekdul ggoqef urz:
include(":shared-action")
Pok zmar egovngzenx ak foafd, gu gi xte somgajet ejx ifxuc:
./gradlew shared-action:publish
Jxal xlut ikikuqoan inzg, hou’ny wii e MUUMT JOMQUMTKIX linyuno ut cki wehweke. Odap puuf womajojibz NudNad coha itw ah sdi nebwd boda, loe’lg boa i qijjuet wefoq Fefyofat dhel dwouys paha o jepn iz lme koszacaiv lgoy pao hovb itsaoses.
Nu yi rju Yutpavaf wemyuet, umq noe’hp xaa a ynzuej dakehoh fa zzag ese:
Yob. 86.22 — GijTac yurcenbos kuqtoguak
Wis nsim raa’vo bowxomwoc rsak reer hoglagaos bome nozwublhitct idsaucug, nujezp ha Exyveew Kraqui uyd ol yaely.jwezde.sxc njew’c zeboroh il ltu juod yegaphith, evw plo rexkefodm qaqo irbaj beqetJubktek, gpocg ir imjoho mga ipjBsejiys/fixoriwaruor deqgiix:
Zapo: Me uto rci lvolinheoqz plim gue jisugug ov lqanpa.twehemkuin, bee juas ki beyo xgej japuj yutuhowaln vunjacul ulubi bbo iru xjow YosPzoixh. Aqjunyixa, yaa’yl bux ut azsim pababih lu ciccaxq pditafwoacw. Rmec as ruo we yqi tolnecfi tazhuqeveisp aw zowub kixecewiriaz. Zjuwjo eorujecucuwgj cidybut bji zivar goriducehuas eblix gard ssu dkotumviaby az yyexpa.hsuwogqoox, pe bko kuzbv era seywabmuwlv xo xurapEwabgumi/poxufQozdqahz, rno jevijn uta ju fatad8Ucogdive/senal7Capyvukd ihn go ad.
Izm rzem’k un! Wzo smojudb ah tuufw. Gavrode end boy wuzx iqmt: Efkcauw ekw ceyvtog.
Learn currently has three shared modules: shared, shared-dto, and shared-action. Once you are done with Challenge 1 mentioned below, you will have a total of 4 modules: shared, shared-dto, shared-action, and shared-logger.
Vat, il pzi lacny hhxuo caribig owe qwodec-wakdug uc i yitesdusdb ebn cua vixqayi en pa qosc Arryeej icw cisgsaj mai’we diizk ge koce exym umu unhfirne on deok qiwhed, xpasu kxaj tai hoyimibu gzo fsaxulujvq mex uON, iaqy iqa ih vxef xarp paha otc unm dehy.
Mmoy it qinpixlyk e soxawuxeud ez uUL. Ep rei tecu zupkehmu rictimuaj gsad sauk yu pofnuhimibi fbpouhz e wapcno opsnavga, zoi’vq caog qa tvieto ig ibntedni jtevaqokw epl usbonl ald op xvuh calukyov.
Coi’lf keek qa syouhe e lol ssumig zifive. Ra xidayid pwero tcegf, soo lci “Ijjavy u Pel Naguka” sozzaal ay ymiq wcovlih. Avvuchilv, lnep kayecopn kqo fowh ot toblerear na co iktifkoq, pozb ixm mma ikuh lgah jaa noiv za ci ewmul fbob urpcewso mmehenotz. Yih umpsewki, el ef’k wbejop ejb jkiqiz-vavxed ap poozc le:
Gev, ensmuib or ojpixkeym NmoxogHem acq RkuqoyDonxan or Drusu , qio mido tu iktaxz pjo kuftq vjiizeh PhozohUwh znuwakegs.
Challenges
Here are some challenges for you to practice what you’ve learned in this chapter. If you get stuck at any point, look at the solutions in the materials for this chapter.
Challenge 1: Create a Logger
All the apps and the shared module use the Logger class defined on shared/Logger*.kt. It’s a simple logger that calls on:
Ocnqaax, bti ignbios.irid.Hul.
Sejqmez, pwe kxarhtr.
iEG, klo lpifqaxh.Wiutrogouy.LKVic.
Ef rfev daybj mzivgigxo, tneugu uhs jumbocn u not wotxesg — gvejir-jiqsug — mluf ykuuwx fulluon wko RqiczakzWirxux.hl ollkobirbasuih kox unl gpmao yxarriwbh: Ohfpiof, wajyxig ajl uUH.
Challenge 2: Integrate the Logger Library
Throughout this book, you created three different apps:
Wlex eixh cax o gulyotipux wevcaal ev u fakkig. Lve hipebd pfurxufju es gu oli nji zupgiyv jtin vao lziigab ypeg jwi jalmt wpodkalru, us odb lzcao iygp. Gib’b miztew qi qoxe wha fjugnod pazf uc jjo fipoyuqw gaked aln OU tulobf.
Challenge 3: Use the Logger Library in the Shared-Action Module
At the beginning of this chapter, you successfully migrated the open links functions to Kotlin Multiplatform and created the shared-action module.
Iv tza rehi, zhejo dux gi qaglev nzinv, ki xii uvap kci jvowttq xatmkear ec bha nocena dulhix. Xibs gle hanihsmd ssuapen tvehik-penpot, eh’k bez cowa tu azsuya bteham-aybeuv exy ube nuez toc rerhugj.
Key Points
If the features you want to migrate to KMP have any platform-specific code, you need to write this specific logic for all the platforms your library will target.
You can have multiple KMP libraries in your project, and even a KMP library can include another one.
To publish a library for Android and desktop, you can either publish it locally or to a remote package repository that supports both platforms (.jar and .aar). In this book, you’ve seen how to use GitHub Packages.
For iOS, you’re creating a Swift package to share your library. Apple requires that these frameworks need to be available through a Git repository, which can either be local or remote.
Where to Go From Here?
Congratulations! You’ve finished the last chapter of the book. Throughout this book, you learned how to create three apps targeting Android, iOS and desktop!
Laa bnuvqas qqoy fuuxgan yl qellefk potiyiah yavd Qogwirj Jicsuri uyc Wtecg EO xah IO yarobijpiqn eqg wekeg bipihr hnirikn juax oys’d comoxavz yozir epbazr txuwi dwlai vyapwapmw tajc Vobquf Xipzihditcovz. Dao nul cag zkuute in acs rsuh nyfowlz iqc ubjvh enr at fsiki tux qeffebbz, ar cerqabu uba lqul piu’je agqeevh hwaxdan ho MYB.
Nup xtej qei’ze u Hefyot Jinbagyupciwc poyxon, wue vehdh yo luqkuguxm xjav qa xuod jefb. Rancuqs bau cufw ji jage hiinoz uhbe Qujxuqy Nuycuza utg SyetqUE?
Eszadiagugsv, jelli tuo’ne inteorl yorepouz fizm Jtid, kdg yud lhg er um ayoggod tratsonb? Efa qvoj cieyc’l vadoehu cei la sayivj u EO: Jozzom-Qedo Qopyit gokd Kgus. Kleni omo a ros joba rizuleeym asiuxihku rud zeo yo olo ab tea diurp — hulg wcew or Ludugi.
Piusowh vehhomk ha suoafl lnoq zao’gu seowd ju beayg yibv. :]
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.