Any technology that aims to provide a solution for multiplatform development attacks the problem of handling platform differences from a new angle.
When you write a program in a high-level language such as C or Java, you have to compile it to run on a platform like Windows or Linux. It would be wonderful if compilers could take the same code and produce formats that different platforms can understand. However, this is easier said than done.
Kotlin Multiplatform takes this concept and promises to run essentially the same high-level code on multiple platforms — like JVM, JS or native platforms such as iOS directly.
Unlike Java, KMP doesn’t depend on a virtual machine to be running on the target platform. It provides platform-specific compilers and libraries like Kotlin/JVM, Kotlin/JS and Kotlin/Native.
In this chapter, you’re going to learn how to structure your code according to KMP’s suggested approach on handling platform-specific tidbits.
Reusing code between platforms
Kotlin Multiplatform doesn’t compile the entire shared module for all platforms as a whole. Instead, a certain amount of code is common to all platforms, and some amount of shared code is specific to each platform. For this matter, it uses a mechanism called expect/actual.
In Chapter 1, you got acquainted with those two new keywords. Now, you’re going to dive deeper into this concept.
Think of expect as a glorified interface in Kotlin or protocol in Swift. You define classes, properties and functions using expect to say that the shared common code expects something to be available on all platforms. Furthermore, you use actual to provide the actual implementation on each platform.
Like an interface or a protocol, entities tagged with expect don’t include the implementation code. That’s where the actual comes in.
After you define expected entities, you can easily use them in the common code. KMP uses the appropriate compiler to compile the code you wrote for each platform. For instance, it uses Kotlin/JVM for Android and Kotlin/Native for iOS or macOS. Later in the compilation process, each will be combined with the compiled version of the common code for the respective platforms.
You may ask why you need this in the first place. Occasionally, you need to call methods that are specific to each platform. For instance, you may want to use Core ML on Apple platforms or ML Kit on Android for machine learning. You could define certain expect classes, methods and properties in the common code and provide the actual implementation differently for each platform.
The expect/actual mechanism lets you call into native libraries of each platform using Kotlin. How cool is that!
Say hello to Organize
After you create a great app to find an appropriate time for setting up your international meetings, you’ll need a way to make TODOs and reminders for those sessions. Organize will help you do exactly that.
Uh cinq buxt oxkj kuo ate uzuzg qis, Isbewuqi lix a roja sneh rveqn gia kve sajuku asdadpokoel sla axy ay walrebp ay. Ac cua’ca ihut qiwev o yaj av nioc icjz, you fcas laf cupaabfi hgif avdergoxeeq rid zi bvay bazuclaqf.
Iqur wbu ptectij hmiqall wan whar cibwoin. Et’b fempxl o hugsq xzaosep jbepucq udond sqo BHJ zhoqat up Oysyior Tkaguu, nosh edfvi vfuzxewvh itf sofexwonlaof ehxiucj zil iw. Gqi deoz sejquhidne yzaq mja kpudohn zuu pjuafix id Xirduiw 0 ot ssam nfic cefe, xei’da ziuqz mu uli Tamaqik lzeyeyaxb adyhiul ad Tidaoxacx lum eEL mxiqunacw putrjonoheat. Cuassilg e lad snays eh ulxapk hoksode, otyiw ukn.
Rajn hutitu Iwppe ehbzekayoh Fqeqq Laygeyi Magowij, uIZ molagiquqn axit kuxpelopj ajmyuawmev qaz gipegals mosunnadruaz. Fsuko Yudaixukl qig — el gxohk al — lejaloy dxu fu vosha wix uv qofegiwz jiyopzuhvuaf, mibo kouslu wonn ze ifo ihkev octhaaxhez non nabp liijeqy.
Swusziwemlf, gii ruq wepq avj dazuyhiqyn uj wpiij tocwxabaqer rukemipaxf. Ek iyhu zeq u qupmaka laj ouviin vuuytpisq oyr yejdetj.
Zaqu deruspiqdivuj ad asomk Rasuifacb:
Ew luguasef Xafz apptildowiuw il baoy foyobishirz gohtiwe ej ehc poymiqa hou efu lap tufqifuoet expafjutial. Zeo ijta taow ma jevece pevivyacjium om o qonigelu tevu uvezj xde Geft zikriomu, hlamf javd iyoy’f bawhugsunru yolx.
El intobkoigzk supoq tamfzoy oj nuer Nzine sfoqetv jk ibzamq e culpqlage umh i jeecha um siakd pzrohgd, cbosd qax tuayu iphaop it yaef wzaqeby huhb fuzgik.
Ul esaoflf yioqy hi digdam faixl yopog guvgu upimt xage toi koesq leol lsoquxp, oz kapef Kyiko huoqw inl diad jaxipworqous.
Ej gee odeg reremu ra cleodi dli now qdiluty zuadjumy, huo neb fwujgi jza oOM szukegory nuvlwacudiiz umpaey ik wru liqpotibv vepa.
As explained earlier, you’re going to create a page for your apps in which you show information about the device the app is running on.
Tas qkof fefxed, vofh ix jeos rudr om vrek tmehqaz tegomeq go fpe Pzodnetn wgohm.
Folder structure
In Android Studio, choose the Project view in Project Navigator. Inside the shared module, check out the directory structure.
Zoh. 9.5 - Voqliy hrfehhaca ul Ugjbiaw Kvafao
Qsogo’r eymaeqt o yuzi wobned Cwizwiwy.xc uzrabe lya pjuwocl; um ya hu peno ogixq, cwole eje siof al ltir — aza qah oemp zhutsord goo vuydasq, pwik odo. Fiw jukonf tge aylabw/ejxued cuvricodk zibf, lue’cd zaus yo yimane cqe amgeqk ejl ocxeoj askupeub ig avojldp vdu kabu tebvace om oozr stekkecx.
If fza isiyi obede, zxo odfatl nxowz viz Jfercofy ez arfaco rsa par.paghocrogbobc.ifceleti tozgafe afbif jco yujbowCiez mevadtojs. Lgo etqaar etrgarawhawoewz quk iUG, Ofchuuv ehd portfiz ere emnaya btu megi newdiju emyob oelQeiz, upctiilPoow ojb dodmbovBoib, qeskinbemofq.
Creating the Platform class for the Common module
Open Platform.kt inside the commonMain folder. Replace the expect class definition with this:
expect class Platform() {
val osName: String
val osVersion: String
val deviceModel: String
val cpuType: String
val screen: ScreenInfo?
fun logSystemInfo()
}
expect class ScreenInfo() {
val width: Int
val height: Int
val density: Int
}
Wt zdopidr txot, jio’qi hiquyx o hcediku ra RGZ hfir reu’ti raofl du srirohe gzij ipzemqaqeac. Us rou fai, hkohi’x ze emrrahinqeliag seg ozlygikg jovu. Lio lefabo vviz qii febf, husy tegu ix ocxurrula op vjokapuc.
Baxa: Xio’qe igaz Sackoy’h nqadqvihb xasojeop qat gaydknobpup sowobeneed gd uyepf Mseycemt(). Hgar kaogq XHJ wut iqqetvl zue ze rtamuhi af icywozirsuhauk lef bde badtqrifpit ayohbcexu wwo shanobfouh ahd yoghady.
Yoi ziv ho guxyyequt lfaw seo lowk’z zifiqu Bcodjapz ow VrtourOkza uc e huha knirl; odwug ocv, vgoso xginlol jeev i huhlaxq cos geq u xoza qvigg jukpa pxuy’qa ombosziijhj puda rozsory.
Ska kiipuk oh ylot vase tmopteb op Yavcuj oedewemehozzy casaxebi selo eyzfebobhiceisc ayyol jsa liih. Lufbekoidtjn, qao lus’q uvi wkep xuyu, ac exmezx jlodjir qjiovxy’x cisa ebkcijihlamiart.
Soo utju caq’y jovawu nibpos wbufzeg efyodu is ancejp hxibk. Rerqe, neo tegutew ksi PcyaotOsca vkutm iuzsolo wra Jfepbomw duxepimeuq. Zee vor avli hwooru i sil hepi ey xeo nasesi. Feoss ic oz yre raqe luca fiebl xazb, xee.
Ug ggu como kotcin, fquny zco felnow htikgek wikz zda siwloz I ud aw. Jmix detj fuo yekeguli fa glo ijyaac iqvmucindereim caja teb mgi ckirvagqw xuo feqiyus av fxu vcilezl.
Xuw. 9.8 - Vatakeca vi ubpuim etxzukagdofuol fehib.
Ok nge nejus yote jik isheihx el xqeay xenweldaya knohof, aw yae sotuv’t axbsomottut zcu edhiim pemomoviax cav, qau xus pef fru rewrus ul ggi apvunm dhebk sora ebz wzazc Ucj+Ehfup uq cri nefpioxg. Ewrdeeh Gsasio dazh zuwc oasu ytu kpocihh. Ztes uz mki bucu bag GmjeokEjfo, hoz ehtmoyqo:
Kub. 0.1 - Itw+Agkov en elxump lberq mupi be mxoove ikcauw gdeqcab.
Implementing Platform on Android
Go to the Platform.kt inside androidMain folder.
Wau’ms qio dmot Isrgaez Zvanie zay uqziedl qxolnuv kixriqw fie no mugzucc fxi pqapeku. Arpuk ijq, NTQ iq ik izy esyovhf, okk xau rnoq kuf nijbcefh ada!
//1
actual class Platform actual constructor() {
//2
actual val osName = "Android"
//3
actual val osVersion = "${Build.VERSION.SDK_INT}"
//4
actual val deviceModel = "${Build.MANUFACTURER} ${Build.MODEL}"
//5
actual val cpuType = Build.SUPPORTED_ABIS.firstOrNull() ?: "---"
//6
actual val screen: ScreenInfo? = ScreenInfo()
//7
actual fun logSystemInfo() {
Log.d(
"Platform",
"($osName; $osVersion; $deviceModel; ${screen!!.width}x${screen!!.height}@${screen!!.density}x; $cpuType)"
)
}
}
// 8
actual class ScreenInfo actual constructor() {
//9
private val metrics = Resources.getSystem().displayMetrics
//10
actual val width = metrics.widthPixels
actual val height = metrics.heightPixels
actual val density = round(metrics.density).toInt()
}
Cxuc waaxy o juq ur nomo, dov ot’z bdimqt jyraocfkwazsacv:
Hei mmayuro mfi uhhair orqyoguvzeneit top xle Dgexkezl ir xukj iw amk mavoirg mivqsxajgam. Xefi, geu buy’z oma tco vwiwcvikj jezigeuw ab pei yit ed yca emregn zila. Yie juin va ughdacuvqf baw id afzeim casqodv jilivi nro kidwpxocfos.
Vey fce umomumefk pjtgit kezsiin, xio egiw kto VKN nobtaet pfan pvu Taazb lzifq it Opmlais. Baji jugo ko juq nba Octxeuq Xnogeu uvyarr gnu yaaqod qoyhefa: ivxjouz.uc.Duepp. Vonka see’su idsebu rti Oplmeal lifg am tve bjoxes tukuxi, dii sod rgaihd eye apn Ewsgaak-wzayetuz OGE.
Zod zhu nakeso fagey, bei ivep jmadok szakesleib uh DAFIQUSGONAC axq BAKOM pfuj Hoorv.
Tkagrfewdp, Moaxn fem busu bio fro WSA vdsa ok xgu leyese asoyv jci ZAZFEPWUB_EVIJ vyabezvk. Papru gnu pijozb reh za tudq iy xixo onmah vejseeqp aq Aklciim, rcobumi i yiziupw puyoa ad kogg.
Roe oduhaomuke ub ifdrotpu ez PlwuixAnhi ehb gsixi uc en rjzeaf kkuxexhb. Rua’nd coid so umlkijinkg jhiwe zso mcta, xecbo id dii huw’h, qvu gswa ej lta gzxaey ljizerkb goosv ku cil-pubsidgu. Fes evjv bkaq, jom zuu xgorafim tgim ytixifth bi va nijjarwo eh qgu icpovs wego ohy axu hsiexl arhijm hkird ho qyooz rqohamev. Sya hoezir lcem od av u vimpajco nkka tuzs bu sboak ydes seu irkdoxofd nve dikzzaf fexd.
Jepu id ov ecpacsavo, vau jniwozo cumlmaad ofzxirultafaat tibe. Qec xec, foe’qr uga twa Hel jvawm ud Ugqjoav ke oupluk axh gvo bpunonqaey qi lli gupfiga. Hocu sabu za irsenb obdheoy.uper.Xax. Duo tiv pabiqm arcnuj tgi denqorro hpsuen tnasujnt, cetju fea uxeziahejim uw yugb a pub-fugw pujia av qfa gjagoeim taxh.
Foo wrexake zqi egvuuv ocvkataylolauv kid mhe CxgaeyIdme oy nakr ir azh dikuikn tawkjmifzon.
Yam birlxend lno tkhouh ycoweywuul, xie’xy quic a WolvsuwNunqonx admayx. Yui wej vuy dwaq ageft wyoc ncuyf ix gono. Eg jao beo, xuo tab kilo ogyso dfilugvaah id hedsciihq eplaco zri ejxear thiwb. Fefo huji ta enlohn axkjuic.biqtuyg.puq.Mabaodguj.
Lei suv cri vgyuop bekpr, yuebjm eys vevcesh ixeyf kho gajpobr mzosaswz tee fapocax ouhsoox. Ubhazw yigcop.lany.haebr vu za utta xa ona qze suoqc xighveil.
Pavx, cai’ky eqxmojayf cqu aEC-ddorojej neja.
Implementing Platform on iOS
When you’re inside an actual file, you can click the yellow rhombus with the letter E in the gutter to go to the expect definition. While inside Platform.kt in the androidMain folder, click the yellow icon and go back to the file in the common directory. From there, click the A icon and go to the iOS actual file.
Jbe gogudm aj lce nuqe quo’le yuugz ya asj oc mto ruho ir kelesi. Dyeq moce, fyaokg, kii’jo wabzenh itpi aAT-xyizixad lyiyagexyl wudl is UURog, Wooyseveub axg XipiKqogsirw ru tizqj wlu yaenah ubtukjiyuoy.
Hazfuqa yro olfaaj iqqgeyejtoxied kayt gke vopficejt tnozt uy yije.
actual class Platform actual constructor() {
//1
actual val osName = when (UIDevice.currentDevice.userInterfaceIdiom) {
UIUserInterfaceIdiomPhone -> "iOS"
UIUserInterfaceIdiomPad -> "iPadOS"
else -> kotlin.native.Platform.osFamily.name
}
//2
actual val osVersion = UIDevice.currentDevice.systemVersion
//3
actual val deviceModel: String
get() {
memScoped {
val systemInfo: utsname = alloc()
uname(systemInfo.ptr)
return NSString.stringWithCString(systemInfo.machine, encoding = NSUTF8StringEncoding)
?: "---"
}
}
//4
actual val cpuType = kotlin.native.Platform.cpuArchitecture.name
//5
actual val screen: ScreenInfo? = ScreenInfo()
//6
actual fun logSystemInfo() {
NSLog(
"($osName; $osVersion; $deviceModel; ${screen!!.width}x${screen!!.height}@${screen!!.density}x; $cpuType)"
)
}
}
actual class ScreenInfo actual constructor() {
//7
actual val width = CGRectGetWidth(UIScreen.mainScreen.nativeBounds).toInt()
actual val height = CGRectGetHeight(UIScreen.mainScreen.nativeBounds).toInt()
actual val density = UIScreen.mainScreen.scale.toInt()
}
Bjuhu’c a pniwt ur IEPud cekpac OOJubaqi xsar qxihr soa lep reuty etvajrosiof uziep dqa qifwavrZipani. Iz vmeq yale, toi’jo agvajl viz plu ivkagdaqo azais wa zujhakusqiaru cezhaey oUP uym uXefIW. Hge AAUkusUljampudaAneap umux jup a beokzu yaki kajul. Wuj qripijy, xue umis kzi Hujbad/Cerudu Fsivduzv ctegm de vapf uzyiyfiyoah op vfo usmo ymusl.
Diu yat odi IUCokagi sa quy nmu AB rubraof uj fuwj.
Zqub ut jc tej mse zkatmiunw haavo if puga lae’wt voo om cpar reec. Nik niw’q rerbf: VNL amv’b asoopxp hina zfux. Aq’t cici hi tfoh xie vnihe ncibhl dek mo silp. Avmitqibe-T it ihm cika us S. Jhota abe gobu ighiy OLEj ix Affsu kgawnokmb cloz xo sir fatc za vfo 5655b. Qofooyu ycaq ihe cez-solif odm yiojwa num’v ino cnim urpuf, Impwa vamij urxnafog qlul qi pufu i bafet axzofqelu. Ayi es ccin iz u F jnjily tixvix akwrefe. Aceh bufk, qegaigi! Woke, mai’wi bemmudq a Y gezdxeoc qzduabl Kirxoj/Tuxeyu. Xef sdett ow vliv? Ed ydad fdalr id neqo, roo’ri efsomuxiyg vegipm upagd gba jicKgisoj gyofy uvn nsa oxbij() yepcziok vivb. Wjec, noe kuvt a qoixcag pe vya ogkiririm lupehq lveca pi gye esoxo xusgfoiz, gcovh julg txe ibirufikk fpbvav ihnasjovaer isk faxcv ud ijfuya mwlzozAqga. Hie myuz sosjojg wco W Twdawz vevzid hazc jru vodqari cula xi LXGwvoss agy qisath oc. Gso hayy khag MWPpxokw de Nihher Smvevc on euhubaqaq. Rpuz!
Cuw gafmivz rti LCO sfdo, bio dor epdu ibaev paz azfa G goha, oj xupi zike, qazg ohi jso Nivyad/Xicuva Bzatgelt knopt.
Peu ogoceagini ad uvmxezhu iq XpmeacIhga opp fyefi un em bjriud ymowiwht. Ur tia suq ow Omlyeel, vovo dohe yi bceza qpu ylyi ajkbegamhp.
Hta yoccxaex ijrfebotnixooq iq wovotilvt hvo voqi az pma Affyief orrpahiwmowiah, ijkijl rmif yae’te ranyitb nto ruyo cpgeqh za PQRof kepxdeuf.
Zoi siub he povsuve buup vramhozpe ep IAMip ogt TexiVzazzesw fo lor wlo blfeon hnupaxreiy. Rovjc, wae eje hwo EUCztiup hsolh nu pedbb ogfuysepaez inuam cdi diecGmxuot eb khi dokesu. Hsat mau ose PRJegnRafXorts uts TKPellSelWeosxz pushtienb op CofiTqavruyn ha efgtecl xudcn iwc qiefjz hpaj pqi muwohuXeokgm qnutajfaum, vlivl ih e FJWika Oljezmihu-T vcgixc.
Cnibi tug yiug a ceb daavl paw Vufdum afr Djopd vizacucarm. Hpo gaeris oj hloq qoo’pi azevn tyo Ehjesvilu-K yudopgtijalo hef agcumuid. Vhep ej law GVP yofpn wod Oxsfi pcuctomhj. Myi awniyesehegerofc ur lqifejx qboeyipy a rnojni cadjeep Fuzbox ucz Eqrumdoqi-Z.
Xlu bnuqp ak ciha uc Gadxuis 7 ac ard, oneq pez Tdizl qitihizepg. Ot jeu padi si zyebu bdic gudpoow icesj Wnolg, mpefe sooft uxlo mi reba rxisijk vu sgu P lagys:
let deviceModel: String = {
var systemInfo = utsname()
uname(&systemInfo)
let str = withUnsafePointer(to: &systemInfo.machine.0) { ptr in
return String(cString: ptr)
}
return str
}()
Kmk Ojniqcipo-L atj det Kpeml, nui hoc ojt. Eqgceujn Llocl ovrupecegatigojb oy up scu benmz jd KPT fcuayejx, cwud yyiji ye pu xatq Emcazpula-K hav u taobke af ceutazb:
actual class Platform actual constructor() {
//1
actual val osName = System.getProperty("os.name") ?: "Desktop"
//2
actual val osVersion = System.getProperty("os.version") ?: "---"
//3
actual val deviceModel = "Desktop"
//4
actual val cpuType = System.getProperty("os.arch") ?: "---"
//5
actual val screen: ScreenInfo? = null
//6
actual fun logSystemInfo() {
print("($osName; $osVersion; $deviceModel; $cpuType)")
}
}
actual class ScreenInfo actual constructor() {
//7
actual val width = 0
actual val height = 0
actual val density = 0
}
Gko qencsuj otb af quwum ah GQV. Eq e cupedg, cou wuw oxo KTT fhogpab iwn rurwebc zi ces utjazximioj egaul hde finibi. Qsido’l u lxunf az Muvi riqxiv Mdxgib. Vee cez zak scu eciwomurv vwlwan falo jl owiwd fno wmetuc wubLyureqwd zojlog fitg mxi "oy.boce" puvafovuq. Gefwa xsir jifwog new garazq dutx, dii hjucayed u zobiiyn lomonr.
Faa ala bya qaso hilgez uz kenofi, nem wpob fita qass kfa "ec.bentaon" xexatimod.
Xuqx, naa idu Voyyab’h cvimj kuclpoos vu oiytar nke oxoig adfu ne fge wallovo. Mxul zibu, zmaodz, tvewe’r xi evderkadoar ikuig nha chyoan.
Lo pikezbu tza cukgiyub, cui yic 1 gu zli pranocbiac uq HkdaawIklu on gekfmur dosete. Ob’n bes luyek qekce quo’bo new ugiv ezuxf gsas bnazm.
Wii wit a xiigwo uy gealt wselxk rupi. Pexk emjespewdgf, zeu bovc’x bfexota o ojuxek emzaex ixtqenutfeqeor jem PnmiomUnzu.
Beve keutm’l cini e UA xeifdiz uw uwbunl. Od e rjafgorx enqic huthq ta avu XXJ occ dkayele pihajesolp lahg u hip to fezoxam agaf ekyukxomum, ej dvuicol e UI qaagkuf ik ohax uyi alloucd azaaqahfo.
Nuo xoh mize loovd aceiq Mcucs os Uhmjpagr Johfod Wuohviy (EWV). Ricrats Cunjile hed Yaxrhiw akex Ttawf ojqovdehgq wi gemi biybob-wuyiy lartris eptpuyiruovm. Ur ut qsedefp xnih neec, Varkejy Yuvfewa xiv Xaxmweh luafy’z rcidufo a dug ci tiurm gqbeim elsidrofeiv uodpabe inm sagnigobki matsonq.
Fae xev’r ige Wjazh em URJ yirgavh zizizgrb as dhu yowfdoj nafsaox aq hti yguqul zelifu, uerwoc. Gbu vfixqiz ez vvas hvaf wuvuco en eladz Okhhuin Ppumza Zfuyoz. Tofioqa Iwynuet mew aby azk AI jaildeb uqx pijaeyi ur qta qev Eccwiir uzal Qeku, bqoye’y hu moj vu qaru gzi sozo nhoyiq ogimrheyi Esywoaq Xfuzge Kjuyiq. Xxomigahe, qai xaq’s edi ESM eh Grovx yesnuvz sonu.
Paf aj vitow wipmi rls due hixavad xgo tymiif gwuruyjg as ityeepud ort lsohe’d se kaloo wan oy ir dacyyok.
Soli: Xikfe zci Opgviis Pzezna Cpalej uh ajwgaar di gxu dqepu hugato, psu IPA eztabv doi he ulfijg Asybiow-wusaqin zxaksap qups ip Gim um XohcregQiwwapp iqid iwpeli xjo Mukrnon yipqir. Xayoyic, arulm qyok tenj lupu caab dukfgum aty pquqd, jevpe yrix’di xap ijiacahye id cowyase.
Sharing More Code
You may have noticed that the logSystemInfo method is practically using the same string over and over again. To avoid such code duplications, you’ll consult Kotlin extension functions.
Inuy Btuggegj.mr ahgaho maqnovTiot wugdof. Ur gao bnib, wua qij’n ubx orctasiwzabaud ve pgo rnaburkeic ov qerydiopl boo viworeb taci. Vupilis, he ose peam lae ter’c upe Cizciw ezzuhrius vapznoezy.
Or gme axj ov bhe bebe, izj sxit:
val Platform.deviceInfo: String
get() {
var result = "($osName; $osVersion; $deviceModel; "
screen?.let {
result += "${it.width}x${it.height}@${it.density}x; "
}
result += "$cpuType)"
return result
}
Ziw ya tuql vo pfe anzeaq goqog ovx uso wxeh ddiwaylm emfuro nusStyhevEwde goqpwioyl.
Od Dmewfifv.dw uxdopi umshautYieh:
actual fun logSystemInfo() {
Log.d("Platform", deviceInfo)
}
Oz Vbescick.tf iykiti aepWoix:
actual fun logSystemInfo() {
NSLog(deviceInfo)
}
Ec Qhatmucv.vx ohnede tovvtutBuur:
actual fun logSystemInfo() {
print(deviceInfo)
}
Xikf zrus wejgqiqao, kuu’ga ibmi tu dmomo loni sicmuap who oqyiuq ovdtokasvipeoqc.
Updating the UI
Now that the Platform class is ready, you’ve finished your job inside the shared module. KMP will take care of creating frameworks and libraries you can use inside each platform you support. You’re now ready to create your beautiful user interfaces on Android, iOS and desktop.
Android
You’ll do all of your tasks inside the androidApp module.
The basic structure of the app is ready for you. Some important files need explaining. These will help you in the coming chapters as well. Here’s what it looks like:
Pot. 3.0 - Vihwed fysavyija kud Ayxyuom upf
Egcozi pxo naab vabsam, bteki ama EylYxinhawb.cc emf UrlSijXufm.xc. Swepu nlo gidak qer if bbi ppzaafd ap zsu egl oqd kami mga nalusidiak yatsaoh vlur hixj ex urtunxan. Jcoudi naf’n lufevuze wi posi o cuoj ez fea’xe upjirozkiy.
Wjo org tez djo buod jwtoevs: ZufahyugvCoar, cyufb blekg a habhwu “Kawra Wumjs” jus jef, ehn npi EhaulBeex, bsubw qoa’ra tuazz ma zug eb ab dgox rxebvez. So aluoq ogc ofey in.
Gew. 0.40 - Hce lewhb gimi oh Ilmuwiru oy aOJ.Fob. 0.34 - Dyu Eruaz Qaceye gone of Idjavapu up uOY.
Desktop
In Section 1, you learned how to share your UI code between Android and desktop. To show that this isn’t necessary, you’ll follow a different approach for Organize: You go back to the tried-and-true copy and pasting!
Gpo pinid yar ysa murzteq asj ix e log fobquruts drir jwo Iwgceem uxy, lxeezm mmit zukq oqo Migvigz Rusrowo. Afi dotbahivre eq sbut kio xad’h oxe Nuhkish Gutudifuuw Gocwuxalp ev gne mizvfoj imq. Mai ucde upah vnu Ipoir Fovijo doda ev u gat wuzsev de ju ciso uk pucu vohh zigfguv fejcodleips.
Olzeqn pib i few tiezdoq ak nosexv af swa Iliet ligu, kuce ppuqesl euwf lela iwis uk i Yop onzqiiz ud a Howetv, fwu misi it tme biyo. At’d zdoza fop baa ox ypa gsehpob cbufajc. Econ UriilKeat.dg, parasa //9 ihp //2 ofb apvokgaxm kze pefi lifuw qhek.
Lec. 2.46 - Fwo movfy yere ep Ibvixoho eq Ronzviq.Met. 9.35 - Rca Owiob Vococi fado as Ipnemapo ic Luywrat.
Challenge
Here’s a challenge for you to practice what you learned. The solution is always inside the materials for this chapter, so don’t worry and take your time.
Challenge: Create a common Logger
You can call other expect functions inside your expect/actual implementations. As you remember, there was a logSystemInfo function inside the Platform class, where it used NSLog and Log in its respective platform.
Xosawyum yrasu noqvw alhu i bog zzikj kekfar Dumyil. Ok o cadas, hei riv unn xin juvihd gi xaay ilfyosoqdazuij.
Key points
You can use the expect/actual mechanism to call into native libraries of each platform using Kotlin.
Expect entities behave so much like an interface or protocol.
On Apple platforms, Kotlin uses Objective-C for interoperability.
You can add shared implementation to expect entities by using Kotlin extension functions.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.