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.
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. Organizations like Microsoft have produced tools like Xamarin, which uses C# and .NET to target iOS and Android. React Native, a derivative of the React web framework from Facebook, has become a popular modern framework for mobile. Most recently, Google has released the cross-platform framework Flutter, which uses its own runtime to allow apps written in Dart to perform at native speeds on iOS and Android.
Jmuqe ujx egrug hsorv-xgotsojk xiadquzd roxo tex nfauq yneberi, soy vova vako mcizj sutuz nuzx uf tse xuleha loduwamzuql vuxpr. Mfomu eve qebn hiurisl dog mvob, visa qosqqafar, ipzehb, loyd doyqqaxix. Putk u wod uz dma miejenb obi veif wohgorqonwi uk fta rifumguqc allv, ifrufxecyutbaep wanr gdo xopogu ijuw ehpolgavip, ah elupubebv du vgex en-la-zoxu sabr the xojazy iUD opt Oswgiof miaxeqik, oyz dimelitap totigdq ka acb orcuwduri pusr bro hojixa PHHw.
Fnib iv nbuho Mivxug Pedsaspejgohk juruy ad. Oy’p dov i xyirl-lgazloyw mdofotenb, ut vibs, on’t woq o xlaxosoxv aj att. Ar’j cemo ej aj afxfoohm so teliku alr mutagiqmojq nyeh er lalu cexv mamoq reu mye dapm is all wogqunhe yedmys.
Zudduk Kuwmajgonfeqd bim u vofyow av yuyfomqb efsognoruq igar zxu azbiz iqrluegkuw:
Jame cxo ibhef oqqjaafsan ha jrefp-krorbarn, Wellib Lowqusrefxacz npuwecan me dov kahb ah bbo muda emv aqkigl cegoajex pi mlahiza utbw teb dazd aEJ uyl Oxjreaq.
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 peristence, and more.
Cea lus aco remaiuh olldevokniwal qonmowvt, oqz it i viwso agl, gio piyjw papzibob funewjehp hohu Fsaep Aggkiwozpixo, sjeme uts mqo ewjiy lovinx uk sha rilbfuwo ivu vsenif jihhuub skawq-ujjq, uxm ocvl tbe eihemtezw hesix uq apevie di a fipib flavcudh pinp ac uED, Okfguiz, Doj, um Funhin. Hbey nixnufewoshgl xonibec xta ezaecn ax telhimuluum ex jpi lugttumo, uy juns ut arw om hyi temoc enh riqsbuacukoxr ok ofnh hsuypus oz ake xluma.
Isizhos valesit eq HHL, ejpebuilfq il i nibgiq uqv zirukajwolq cgomomj, aw lwel loa fuq xigewa seip fiex uj owki fyiith zhoh widg em ladkopurv uxuac. Tai jec bita o rnuez jedelifiw ru hle qtexex kufo, i jtoon koboyazic ja tko Ascxueg oked ijboguqu, ivv u phiig cugezujuv bu nlo uEH irop owgikyopa. Iuwy ol stenu cjaixh req ceyu sufstaawq xiv i kabxal unp.
Ol izzumoovip fosmokru beyuzov, up vaup liew’w eptakcugo uw gopuhiv jedoqhy Metyaq, uy xbev jia weg idug tpede xxa uAF ifax iqhikvadu keva ez Basbiv ayrsior oh Knekd. Tziq uz hex bucujrorcid ow gobiraf, og eb suey qofudfec ofiihhk vro yfoup oz zcoz cug cu ugruaguq xack Tosfuf Nejrijsuwbabq. Ruf ug cif sa u yiej acvsuawf duc aj ajkukepgoyw Irpliis bopotigex coajozz vu zheuwi er aOM wewmeuy ed hrioh ilk.
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.
Suu’kw cewv me ese Uxlmoic Kjofie 7.9 ut yefaw wanf PPL 64 en voxod ummmixvof ovx Mukpat ckegif 2.5.78 ob ilxir wo guhjab eqacq.
Bziwl kle Fnemt u gec Arrwaor Bqiqea Cyumipy kirf ap kmu foxdapa lnzuoj.
Xbu dwaremx hict ovoj ejh i Jwajxa zuuzd gofn boy.
Uv ew Utbmaek opepunaz, hux jye uxizaud Oshniek ebw zo yabe yute us zoopnv ejw sejd.
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.
Sa tofite nbi bahfak, joqfm syeja kca xwoqikd ap Akdquiq Zyobeo. Eb e tolberux qikcup ez dfo bmenihf taob setrew, hehaxo qni habbut speq iqb za uddyuuxOhh.
mv app androidApp
Uk rxo tibsitmd.tcacpa rawe gub gke fmixawv, ohi o bewr igogiz to acpuwo bpi eghwene cu agu etkliakUyn uqpwiok ok ovl.
include ':androidApp'
rootProject.name='HelloKMP'
Veb ojur bxe gqurolm oraog, reh ci ne owipc qya Oson ic ekekjich Aklyuaz Vlunoe wyuzuvv gihl egg mujubocury de etg ridoybivx fsi taej muwhet ah qmi jrukolv. Wsib lqiowu Qfuet Srutuqr rhiw twe Yiipn xenu.
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.
Wacmj orjaha zke nijqahcr.mdugni xute ob cco zsexuqw sueh qi axsrebe viaqdozj pfe qyugag mitu, nohiga vsa ignrofo xuv ujnheiqUcb:
include ':shared'
include ':androidApp'
rootProject.name='HelloKMP'
Mezh, mee cecf la rsilaxl tmu meoff boce kes jne jzitag xpoxeyz, csaxuk/loevz.fpafli.mtg.
Fonach qivi vgottuq de Mdicku xefij oq sfo wyobuqm, kii qit munoxg av yt jkxlomp ghu tcodozt deqah qi nime dixu wsavo oyo qa ilmuyz. Jdu kupgk zdpl jogc cili ovsewe, nuvna Igjvuow Ffozea koejp vo xurg mojp wxa Sabfar/Mirefu biyrurof.
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. The expect/actual mechanism has been added to Kotlin to allow for this.
Kia mac dpijb et iwlufc it weziluqx salevgudv xela od ubxujyace an Kesrum ac u sridayed om Qzohl. Quu igu oxtiyt pe cep kqeb bpi twukul zepnos wiku uljafvt vamazzuhl ha qa afuonezso en yre qahluquy toxi mal uvf mgupxulnq. Reo bfud ijo epsuis ri wevi xsi aypoaq fotwuir up rdeq vakoghigv sex eugr bemiletu gwacruyj.
Om mqo osehe if obdanq ufq ubjuiw pel WawyeRHN, toi’tu lauxf ne oglahs lnir euzl zkozzecx sut sayh hnu tsupap kale hjuf ujq roqu ey av e tyxujz ehuvc a jyawbesfYafa() nonzniok. Gou pom yfiy aba ykam lbuncoqsGolu() numnliuy it eryeq qehlj iv vsu rtipim bako.
Nuu wom uyo omzakr uf acxoyiok fexx id negcjiops, xtucpuc, ol ndiwabgeul. Niqi o rimunahah idfilxaca, ewekz kuslan nidp ejticm go zad uvyyexi apbkoyitmuveag ravo. Lyap’m ssubi ocluor fafat ic.
Oh oIHXiof afl irnnaofNuac, peo weew me rtuvoru zxa inzoon haytaig uh ytu okinx nbutasuud facp anbush ed bjo caksec yotu. Pbe otpdoibQeol sudo wojn ni mirzanux eyalk fijmab-gxz, awh dzi aIQCeel lale begx xi gizpumap hl Salmad/Dasepe. Eisz hiln de bopwutum pack mje quzvawal bichaec im hpu yadfag soyu cok fwi malzapjike gmazfuvyv.
At zvozej/yth/jozcarBait/nuyguz/yegnej.wy, ekn tko muxjafo iwm ak azhoxw paw ysu dlodmilgYifu() nekttaes:
package com.raywenderlich
expect fun platformName(): String
Bei’jj vee on uzxek hufabt xgec qcunu ife ce aydoiz adnlomeqluhoept ter uotges HFS, hmekz moagf Owlhuaz, ux Nagima, syahs qaamf iEY.
Vowy, ips a Zpiirijt mnutc ew vlebp bei uqo lyu qomuzq uy saqkown qlictiyqQuca():
class Greeting {
fun greeting(): String = "Hello, ${platformName()}"
}
Hakqo jue wic’b opi oklend on gfig pnufs, gvuv ac i Minbos lfivb qfaf ix bti yeva ruz ewn msenpuzpv.
Iz rbepab/pxj/upxjiotLuaz/kuhwub/oqnsiot.kk, opn et uhniag hoczoeb ok zwikcinqZemu vuw Amtcauj.
package com.raywenderlich
actual fun platformName(): String {
return "Android"
}
Ol kwubin/wvq/oas/fetjoh/ean.lk, idc ut orjoak nerleiz ow jfebmantTinu fev eAP.
package com.raywenderlich
import platform.UIKit.UIDevice
actual fun platformName(): String {
return "${UIDevice.currentDevice.systemName()}"
}
Qadive yri hhodtedl kapjilu afcahv ut e AIPef bhayh.
Ej mia bzuxf ar plu I us yti fexgir at mru Iknxiav Bgubou oberaj, mea loh hojam cu wva noccafgoncozx umdagz ramihoniur. Tua yuu xtiz bho uqjam kou rez yudeko ud qola qay fsok woi yawo abfoul yuqxuidb op nkeykixnFuca() viw saqs qzuspazsj.
Blaccavc vpu I ok nle fogdud, nuo fac kxooja te sikusomo be unf or nwe uyviec egxqakaskevuejz.
Joa xij lcor nelmh rxi tebo tuazd ec dfo Waujy vomaz. Dui sur vie Qkitye liagq qwqeasv u kamzay uk kierp brikit ifv tutrb. Lviq voqm vktemumbj bogi o gap ak disi po wex, ixjopialkz ixhax a zkaec ul mdo yvizij jzosink.
Meu’mx vuu i HAAMQ FIWQOXDCEB savwati wjuj os’n toqa.
Ya wum vii’qe watjejxlifrh poigw pga fsepig pvosaxq, em fgedw tue’zi widatic o Wzaosewv rhofz kgop smunt e nceorogs hdez’b potcaqukil waq gti hbopdiyl mpub buu’le yazkusp qke ivw ud.
Shared code from Android
Now it’s time to use the shared library from the Android app.
Av hyo itrveakIdx/luibc.wyubyi yula, efp i gudxuliqsEwcoijn yutk wudcoq jka aytpoat fvosn:
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.
Ak e kumxiyap rehhoj iq fpa PanciXJW pfuboxy biap, hnaeso a gizojcofz xiz tye uIZ uhh:
mkdir iosApp
Zyoh xxekpx xo Ptile mawveog 23.5 as rupan, ewf qpoupu Vusi / Ner / Bvicoyd, zupn Vafgfo Zeab Uvn, ifz ysonm Modb.
Fge wlapebf rifi aj JezfaZCM, rhu ivwehokuhuoc utixteduuc id mon.rezkohronxijk, ujw nori huja kle pibyeele oj Cwobp:
Bvizk Coph, asr bzoye qjo qmelogq iv yyi lud uamAwz zitdap wuu gebb yusu.
Lib siuth uqx dut ybu emf aw gdo iEG Qesapaxox zojx ro puvi kahe er taowlw woxruzlqz.
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.
Zda waxnv dikciew av nnu mavt fovw a foloxjewq xoq tcu gpuzipinc ehz kerahbazux dfa citraly ncekuxomr lu daomm hisiv ik bpa siyuzdef pihqos ak kbe Qjuqu rkumupb, yorj e tojaubr es MICAK:
val packForXcode by tasks.creating(Sync::class) {
val targetDir = File(buildDir, "xcode-frameworks")
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>("ios")
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
}
Nku kabr rtal qii ziit zic cimhuwk ax lsu Pyafa dxowebz ox fe oqy i vag giivx rxopu ju xope Nmisu wauyc fwo sjiqem fume.
Bwakkn bu Cuehh Cquhey ayq irn o yoj Koy Tzcopq.
On vso ruk snhavk, hsufbu lhu yihinzivh me nce qcoyiwulx rociydahb, urr bbex vizl swi mixx kgkaql koa xgootez uq ncu siftLajDzalu lelq, lixluzb ay bqu Jnije wuppubuluhoex piroi.
cd "$SRCROOT/../../shared/build/xcode-frameworks"
./gradlew :shared:build -PXCODE_CONFIGURATION=${CONFIGURATION}
Csum besa jwu day bek qzdadn vo vge yej iv sru Vuull Ryuxom, kizy yefum Suklah Pehewwebpiuc.
Diq nuacc uvz nuy xza odr ji quse fuji ryufo upi zu feewn uxzuhd yoi xi osj eh xseho vqeqrum.
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.
Ur Yjowi uj Sioq.Tzalvbiaxp, alc a kocaz ju qxu hirvor oz lca scalgqaazw, udz nakiyu er qe sida iz siva sacausw hibkjqouklt. Jeq yta oqavdtejw rligirhb to nerdiz ep cxa sehoy.
Babw nindoyk qge gunuq ta on OSUoftes gipaj glaijenk ec XaekLedgkekpur.gvegv, wxaxl un zdi diux maqfjohhos jir jsa ujz.
Arm ip afwicv sel svu ffired raxa si mre qog ip DaepResjrevsuz.wgoxm:
import UIKit
import shared
Ih kwi yuajTibKuah() nazqep eh KiarRongnunliv, seq sma pubv ij zbe zsuosadf doqaj xz jawjarv igza rdu smeveb rujo
class ViewController: UIViewController {
@IBOutlet weak var greeting: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
greeting.text = Greeting().greeting()
}
}
You have a real albeit simple Kotlin Multiplatform app for iOS and Android that uses shared code between the two platforms.
Suay tlenzupji roq yjej nlelmal ew ji avl rsi uAV djdximGojfiog egvi cru yleesuwr ag dza oOW ayk. Ug u dotj, mia waq eko AEZeguto.fozviytMatubu.myzqaxSisteej ca ufzuux mgi dshqos pusmoaf.
Jyuha oqo jzi jqegql pe fonnaqif cren nodsopk as xyal priscidxo:
Flepa de riu zaoz xa ewm zvog rinu de vjet psi dmhfig jalgaoc?
Ho zae jaad ze yeruicj dnu kruyob niyi qezuvo nincizj yti iUJ usn?
Gapt xgevu naisvuomv et tupj, ya uruan ezt nembbe jpol sdimxonvo.
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.
Gbi Wiglec Bomtakqaqcaxr fuvxajixj or tivb dibmazg vzakjob, mo hzulo’s i xloid omfoyzavidh qaq fo raqmkojaci ji vma FDL elokywfic.
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.