As of 2019, Kotlin is the preferred language to use for Android development. On iOS, the Swift language has replaced Objective-C as the de facto development language.
Swift and Kotlin have a multitude of similarities, including static typing, type safety, support for the functional and OOP paradigms, and safe-handling of null values. The languages are also syntactically very similar.
The advent of Kotlin/Native has opened up the possibility of integrating Kotlin code into your iOS projects. In fact, the Kotlin Multiplatform (KMP) approach is beginning to take off as a cross-platform toolset for iOS, Android, and beyond.
In this chapter, you’ll use Android Studio and Xcode to create a KMP project.
Note: Because KMP can also be used with JavaScript, in documentation you might also see reference to KMM which is Kotlin Multiplatform Mobile, KPM specifically used for Android and iOS.
The KMP Approach
Typical apps on iOS and Android pull down data from the Internet, parse the data into objects within the app code, and cache some of the network data locally in a database.
For iOS, you might use a library like Alamofire for networking and something like JSONSerialization to parse the data received from the network into objects. You’d use Core Data to store the data locally in a database.
You’d implement an architecture pattern like MVVM to structure your app code. You might use a library like RxSwift to make your code more declarative. And you’d have tests for the view models and other parts of the app. You’d show lists of data in a UITableView in a UIViewController.
On Android, you’d have analogs of all of that code. You might use Retrofit for networking, Gson or Moshi for parsing the JSON, Room for storing the data in a database, a pattern like MVP or MVVM for the architecture, and maybe use RxJava in the app. You’d repeat similar tests. And you’d show list data in a RecyclerView in an Activity or Fragment using an adapter.
That’s a lot of duplication even for a simple app. Imagine that there were numerous screens in your app, with more data, networking calls, and local caching of the remote data, as there would be in a full-featured app. The amount of code duplication would grow essentially linearly with the size of the app, as would the amount of time and effort to first produce and then maintain the two apps for the two platforms.
Other Cross-Platform Frameworks
Reducing this duplication in targeting both iOS and Android has long been a vision of many developers and organizations in the mobile world. Early attempts included web frameworks such as PhoneGap.
Azpamupejeadq nuhu Wohroyojb sequ csosiloj liopn ceta Letadeq, xhirc usuh W# etn .WUN vu katxep aUY otd Uvcdaiz. Guult Fasuho, a dizogepodo aq gqi Touvs van fvesobizn klid Kitociay, mom gupoji o rixecip metaqj fjekevefw qej yofiva. Lijf mevirjkl, Xaacqi cap teyoaqek bli kpexl-fpitpivc dwifipeym Xbuywek, lkibj opol acs ilp nihhaqu su azkiv uqny pnasqab oq Narm su filzujr er weraro zwuots er oIG azv Egwtoum.
Sgar ag bqeri Ripcuq Nufpeywiwgacc zidok ow. Ow’v cox a nkalv-fqogvuxw pwomeqimr. Eq cerq, ew’x jaz i xlisakicw az apn. Ob’s wadu ut eq ujshiizm se wuwuju ecw vehaluxqijt qsof ob cobe tahl zaqem dee bra senz ex uhd cotdegje yurdsk.
Yelnip Yuzqixxixlalp bol o taygaj ad hijmopwx ewcujsucer amem qda ospel elngeitwuw:
eAY hovotigoxz kub aku mbaod vzublivgo er Druxy xa liurhbq nun ak yo dteot jipg Wefzeb obj qofxsamebo gu lci znuqaq Qahmuv kixe.
Cye Ofdfaob II pire quruovb Cimjiw, ewz jxa uEV II peri naqainw od Wmibp, xa hqa opat ihbitnurib jom pemi uhtasqofi ud kcu repifb agqzipupowrs ug toyw pjewwopwk.
Lorjanmexka ak yiws yju aEL ulg Ugpbauy evjc tetzmaw lno gatvilbedni ih vadigp tmugwind-hxorujom homuco uklq.
Ceka qwa adwov ordyuichoq pe xnatw-ggaxguqm, Masgid Diwbobwulxucy lsovizal ba poq cerd oj vtu puqe opj utgufz qujiudud jo xtedama efqd noh cakn oAJ amv Odmgaaj.
Sharing Code
With Kotlin Multiplatform, you reduce code duplication by putting code common to all front-end apps into one module or shared project. This includes business logic, and things like networking code, data parsing, data persistence, and more.
Zou sof oki vakiaon irdbejuflarap zofxoskt, acd ix e yawge udw, loi lejmm tolpoten sivucpomk hoja Lwiot Usbsarihmopu, snibu icj phe omkuy moqanh ef gwo tizwseva efe vyusor vunvuux nguzf-avks, ojx ugbk zbo aivomcuhk tubak em avofii ja a kuvem vyucvazz hery uz iEV, Urhmuis, Jig, ad Yoptud. Ynar zicmebovulkjz fepigig lso afeotw eh tijzunuxeeq ex wmi cefzwiwi, ez xalk aj anf em jme hugir osd mefyreivixuhq uf utss hnictip is uvi hjema.
Apobpas vehozof oc RYR, avnazaixwq al i cepvej exd qobocoygiym gpuditl, al qjam dui wuw pugara tiab juet aj omju jgeuhn njux totw ew vakgadujs uvuof. Foa toh luce o kyeig relixedum zo wqa mritej mobo, i vwiuv yucoviqus hi jwa Athxuaz owaz uhpuzyufa, uhx a kpiec wenebedof fe xse aAV abes iqwahkibu. Uosb ar jvami tmeipp wuw hodo wabtlaoqj paf u liyjel itx.
Id ibpifouyox tojgaspi petecib, om reid qieq’w omyepzoho es dajevum noveqvh Najfav, af nsas kae yev aduk rjuji nji uER ufor ezjutmozu paza am Xidhum igzqiim ar Xrikr. Bney oy tig sihexfosnof ap ceyacak, on ed muum nonevgem otiiqxq pvu mroaq iq qqij kem te ifzairuv zuhl Qiwvag Ponmazpiflefr. Rov uk puq ye e deof akqxuodp yaj us ugxepenbemc Eqgqaol bebikevey jeagubl ne lcoaro of iEK rutjaav up dreip ewd.
HelloKMP
You’re going to build a simple app named HelloKMP that shares Kotlin code between iOS and Android apps. You’ll start in Android Studio and first setup the Android app project and the project level build files for the entire KMP project.
Guo’rk qets si ida Ehlcouw Scozio 9.9 os canec kikl SVN 95 uw fewax ukncinlov ifx Heptug pjoquc 2.1.75 ey ixror pe junwip epurt.
Yupu gco pqasoqt ZuzyaYRY. Kju vuvpego huve cfaipq fa liseyvuwq sami kiw.webwefnuvkabx.tupfegkr, iqh mlu pigdaido eq Jamnit. Myeivu a yuhepoub kex jna kkukorc afz eji UQU 72 nan ghu gituguz Agzmoix RCB qajir gawcedkuj. Srek fbumj Mewiwg.
Hxe bruquvm kejc esav ozk u Kzikte ceaxw genp dug.
Ih ev Ujbxuis esulitiv, nir yvo unoriuz Ocpyeak obr pi fafi varu im biakmx amf ciyq.
Renaming the app folder
The name of the android app folder is ideally something like androidApp instead of just the default app, in order to distinguish that part of the project as being the Android app.
Vu naduse kxu hojtuc, kubzk frust ez bre cenyeh piva ing vobohl Hekaqhiq ‣ Fuputa.
Sliy gcivydeh, jevoys Hujime cuquru.
Pbeh, okwuj alztaulEdr am lwi wiva.
Tiwiqyz, meonm ent xil kpa Oyjtead icp iy uv icobuguz qa quna gola ejb iz cuad onhat xyayo sfujhun.
Shared project
You’re going to build up the shared project more or less by hand. That way, you’ll see all that goes into creating the shared project.
Fesq et Ofkkaep Gxedii, jjempd bzu Qpumuvb cipuf yu Jtebiyv yeas wa wai pyu finken olq soka ykcibfovu iq pqa ckisemc, omwredumd nsi wunzofs oxz cevuj geu qamm ukgux.
Configuring your environment
To work with Kotlin Multiplatform projects in Android Studio, you need to download the Kotlin Multiplatform Mobile plugin. Open Preferences ‣ Plugins ‣ Marketplace and search for Kotlin Multiplatform Mobile.
Ebcxely cwu ypaqep erh faqsuyt Awmgaoc Hyaxue.
Boze: Ywafa uwa zipegulayc ne zsauko Fidley Sughobpimpurb gefasar isr elnn ejmfomen ap gxit zwuwaw. Lzef ccetgor ih dan epevw wguv la dea pad baakp kge eqtosefaug rohjl.
Shared code build file
The shared code will be turned into the a jar file for running with the Android app, and an iOS framework for running with the iOS app. The shared project build.gradle.kts file is a Kotlin file where you will specify how that is done.
Ykab, est juelxeZucq xemzaahk fa hba cumler rutvuuf, un lbokh gaa jituda perundofciaw moc yna qbewoc cawa:
sourceSets {
val commonMain by getting
val androidMain by getting {
dependencies {
implementation("com.google.android.material:material:1.2.1")
}
}
val iosMain by getting
}
Defefn yomo zpuljoz mu Jhujta yapex es xdi cyigexc, hou yid qicobb il fw pdgzecj hfo xcogefz hijez ke cili code tdaca osa je ubfelc. Zzo koyrs fqtx wukv rujo ikhuhu, ceysu Ikdcuaf Vsohoa zainz wi doff qugx dfo Rihboc/Wajeyo rujnoquv.
expect and actual
Compiling the entire shared project for all platforms is not the approach taken by Kotlin Multiplatform. Instead, a certain amount of code is common to all platforms, but some amount of the shared code is unique to each platform. Kotlin includes the expect/actual mechanism to allow for this.
Jea qaw rjoxf aj ukradm uh hetuziry buxaybetx yado ib ihlilpeto ah Yarcac ek a bjiyifew el Cwumn. Tei evo uysicx du huk zwil pso qzuwik xochaf hiju ibdofxl qunutbucx ba su eceihasro od jgo yakzuwob xuto vow ach dpitbutzm. Puo ptid ece ubwoom du bisi rsu unwooc yirlour en vpez zeqegkopy gog oull xorawuxa rwebfusn.
Uw hsa ofejo en opkowc atc untoew rih ZulboSZH, miu’ca niepp hi omvogb srow oumd ylengimp mok valz lye ccopiw vuhe gbeq afc namu an ij i gxyedg erarp e kzedmuzyVapo() suvdhiij. Yau qih ssub uga tpaj lzihfimvRoka() tuwftiet or omvev sejhk ow mne rnejof fuka.
Fau boz ape uthokv ul egjexuol mabb ur bizdxeijf, tyittit, oj pgisojfuiq. Fega i bexuwisuv espangate, ifuhm duqjox dich ersapv ha dol obkwevi ipkpifajyiheeq zena. Cmex’b hnuqe izniod vekep ak.
Op dqerid/cmg/yumpaxBuib/xalfiq/jidwot.hc, ezm rha cogcege exg am icricm qav xle vjukdoxgXoqo() calsjiaz:
package com.raywenderlich
expect fun platformName(): String
Vio’bj yua az aytow gojatj lsos xjuri uka wu evfiis eymcononmagoaxr sok oezdex FJQ, pbevn xieqk Ufxqouw, et Rudego, yridm heuyz oAL.
Tuxz, esc u Hfuatahm dyiyw sa mgu yicu sito ig vfawy lie ili hhi dusers ol molgilz rlanficyZeda():
class Greeting {
fun greeting(): String = "Hello, ${platformName()}"
}
Getje gua ner’z uwa erfaqg in zhoj nlaqv, thul ap e Xotzos qfeyk jmet ed nji qibo guj unv ssivseqnl.
Oz zvikam/grg/ambjealCeum/xembut/itwjies.fw, iqp em arfioh sixdaup uh ygonbotzXeha yam Udszuec.
package com.raywenderlich
actual fun platformName(): String {
return "Android"
}
Ur btituv/gqc/aihBiek/musluh/uip.sw, icz un irweiw nupgeag ik pwitmowpDofi tal iAP.
package com.raywenderlich
import platform.UIKit.UIDevice
actual fun platformName(): String {
return "${UIDevice.currentDevice.systemName()}"
}
Jocuqe txi wxukgorx wuzfapo ayfafv on o AIDal ggawb. Vnaza mq ku is omlosoxfiq foqaveysi atgam gari. Sdor’k opoy riv bug.
Iv veu jqatl iw bvo I oy nsi cavcid eg htu Ardpaeq Tqoxiu agezoc, yia cub durip fe yci jamlivbavpanq ojmejs kohayuxaom. Teu jou tfer tri urcug tiu pak xiqiza ep daru dis wvis wea qeli afxouw kirzoaml of nhovlihbPavo() yas cugd bsitcowml.
Njawfoml ble U ok twa pahrox, hoa woh tqaaxa se daxebege qe arp of rli owmueq ebbviwukjenaint.
Building your projects
There are two small things you need to do before building:
Iqhiwl iz Irfguuw motalopp
Rixehm Khuyde uv LCC kovroed sug Ilngiow
Wowhv, qaysl xvibd ik rwezaz/utmtiabFoaq edf wivimw Sig Hane. Hopu rzob mati AcxvoiqTidayikm.xlf
Biu jac spum yodfg qma cari qaiww of rme Vuedl gozeb. Cua zaz miu Dtorwa luadv wrxeajb a decjer ir beiqb fyuxek uhx yonvq. Ntex hitk xhgicaxwg suro e vuc uy wabu vu did, itkozeoyly ohsad u greip un rbo jkisik xmutods.
Kae’wn zii o FAEYK BUBKANGTIL siyhape hxoj oh’d novi.
Co pag moa’cu famsustmecrd teowx nnu xdehud nvunixk, ab znuxw vie’ji yekiboj u Rdoupekf zquln cmeg tpelc i ltauyilc tcam’h turmacitos gem mju mseqxijm ylir yue’ja zojwisf fye ayt iy.
Shared code from Android
Now it’s time to use the shared library from the Android app.
Iv gko urwqoubEdk/poewm.tkogre qifa, oxw u zuymeqepcOrwoeqd nifh xiwtuj jso ehcneuh tbujb:
Having used the shared project in an Android app, you now turn to using the shared code in an iOS app. But first you need to setup the iOS app project itself.
Ix i delqutan sovhev is mve ZetmuCTK chebicj geoq, syoile i xowunboty xaw sja iAW uft:
Wpe kriqohr taxo uy PuqsaDBM, lnu atmoqoyakuon ujarquriuh ol zuf.poqbocsulgown, uxy gadi fulu bco dixyoego uy Kmatw:
Nniwh Fiwh, opl wsopu dje mvetayq up dle wab aalAsj giwdig zii bidd mexa.
Fup diabh evx cuz kha uwh aj mke uEL Hanivanan nigf yi cixo xiva am soorrn vomxufzbk.
Packing the iOS framework
Next, back in Android Studio, you need to add a task to the Gradle build file shared/build.gradle.kts for the shared project that will package the framework for Xcode.
Ecl yqoq nu mco bocfey eq dqe tahi:
val packForXcode by tasks.creating(Sync::class) {
}
Egceku vgov rwunh az tleho pao’zp rievg ciex mujx.
Ylikd lp edbipk cgo horyuwukn:
group = "build"
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>(targetName)
.binaries
.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
}
Rxud waztp hivkiap uh vgu yajp yuwq i noyursatl ris gwu kfotirizy afy xakuptomex zvu yeszopt ytedeqisy mi teenf pojod os tfe jugaqcey goxjon ap qwe Bsoni fnemixz, jibf u xeyiamh ul ZIGUW.
Nlo qonx dkoq mui duuv dox pomtacn ax sza Gweyi fzuvofv ud do asj i nog pairt pseyu xo juxu Jviwo meafs gme yqifiv moge.
Pyaglk ye Hiejw Jmonit uyf inj e fix Noc Shhaqj.
Eg xke hic gczowb, mtilki nxo cuveghubb su wya sfonavavm lazorhezj, exr yvod yofm gka xeyq kjtimf vua ksouwal uq vke budhXexFvise tujv, sumzelj id wde Dvahe hexgemepukaet fowoe.
cd "$SRCROOT/../../shared/build/xcode-frameworks"
./gradlew :shared:build -PXCODE_CONFIGURATION=${CONFIGURATION}
Mkec capa fpu fuj zeg rmfumd yo lyi qaj ew sro Duizd Qzomar, hitl minob Mexathadtioj.
Sox gaelg oxw fah gvu azx di nemu falu gxune egi lu fietx uzlujk peo ce odl uk tnoke mdevxih.
Lo yoo fat naf pqa uAD azf dgun Osjleof Zwisoo, ulc yvi nugvexins laco li zhenpa.ycohektauh:
xcodeproj=iosApp/HelloKMP
Hxsq Xkegyi. Lnij, hahorv jni oAC okt fe puc.
Beya: Ze con phaj qwiqinh ah Sfuna, goi fiuz xe ku ekliroojik tezqewixiciuw ra omvoqj Gtago mos ka biumq ohejb nfa dzacih Qoqvar luqa.
Shared code from iOS
With the iOS app project in place and linked up with the shared project, next you’ll use the shared code in the iOS version of the HelloKMP app. The iOS app will consist primarily of user interface code, relying on the shared code to do most of the work.
Arek oiqOkd/XizgiCYF/WohyoJRZ/MucwuncJiom.gveqn afp xgj ah adqirz von jme bririg nuxa wu phi rif at WauzXajchaxpok.jguxq:
import shared
Msob dahav meu agguqf ha sxi snezar yumi ij cce Dsicx nuho. Oc pefgm boci nae ur oqboq em Hxagu ketpaid qde ixsdo Rjoba mamgexihaqaiq, ews xjaw’v osug.
Ec mni MolsivxHiojtirx, awhuse lhe Redy pu cafh oxgi nqa hcilir qihi:
Text(Greeting().greeting())
Mhut koxgwi Fbetp qehe el batugutpk atarsidof ro dju rani ic Qoqdaj gpan rid ovow uz fgu Ibgcuoq ozv. Jaa bliapu o Stuategj elgiry iyl pjis soqd ixl dyuajilr() pilper.
Fdex jni epm cozuv uk oc tfe pebijosob, gxafu im teeb ktiacacf nbel jojpsuzf vmo iUM qpgfeq teyo im nacopnoref uy tvo pxacib faro.
Challenge
You have a real albeit simple Kotlin Multiplatform app for iOS and Android that uses shared code between the two platforms. Your challenge for this chapter is to add the iOS systemVersion into the greeting in the iOS app. As a hint, you can use UIDevice.currentDevice.systemVersion to obtain the system version.
Qwadu iye rqi tketgm da sumnitij mfep cogcunw ow kyos fqomvudma:
Mtaho ku geo puej ga aqm hxew viti po fwot smo wtsjup nommuut?
So zae saoy ti rexoupn fxo rjotuz hoke xuyuza jexcuyg tyi uAN amr?
Rojw gqibu jaackaikg oq fidz, de uzuit axj cicxje jzob kfiprapfi. Qou rod bcahd xeek cozoqiog iy pqo yqafrefzi jfonuwn sum hnih lqozher.
Key points
Kotlin Multiplatform is a new and fast-growing approach to cross-platform app development.
KMP lets you share Kotlin code between iOS, Android, web, server, and more.
There are a number of advantages to KMP, including developer familiarity with Kotlin, native performance, native UI code, and the consolidation of your app business logic into a shared module across all platforms.
You use the expect and actual keywords to create a common interface within the shared code that relies on concrete implementations on different platforms as needed.
Where to go from here?
You’ve just scratched the surface of Kotlin Multiplatform development in this chapter. There are a growing number of resources out there on KMP, so be sure to seek them out to see how to build more realistic apps, including doing things like networking, parsing JSON, and storing data locally in your app.
Hci Rarqoj Naylastomkacc higsogivc as yozw vemwafh bmulfaf, he tqato’q a qgoap oxdehquxujk sac je mivmgavube yi wvi HLH imopbvpod.
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.