<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>More Platforms, Less Worries with Kotlin Multiplatform | Infinum</title>
		<atom:link href="https://infinum.com/blog/kotlin-multiplatform-overview/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/kotlin-multiplatform-overview/</link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 16 Apr 2026 15:26:52 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>8155https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-0.webp</url>
				</image>
				<title>More Platforms, Less Worries with Kotlin Multiplatform</title>
				<link>https://infinum.com/blog/kotlin-multiplatform-overview/</link>
				<pubDate>Mon, 29 Nov 2021 14:15:00 +0000</pubDate>
				<dc:creator>David Valič</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/kotlin-multiplatform-overview/</guid>
				<description>
					<![CDATA[<p>Kotlin Multiplatform is a cross-platform solution that allows you to implement platform-native UI while sharing all the business logic layers beneath.</p>
<p>The post <a href="https://infinum.com/blog/kotlin-multiplatform-overview/">More Platforms, Less Worries with Kotlin Multiplatform</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-312"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	If you’ve ever developed a mobile app for both Android and iOS, you probably had to code the entire app twice – once for each platform. Writing the same app twice isn’t very effective, it’s time-consuming and you might end up with slightly different features, especially when you have separate teams working on each platform.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	Many cross-platform technologies are trying to provide solutions for this common problem. Maybe you’ve already tried some of them, but weren’t too happy with the results. For example, the UI didn’t feel entirely native or there were some other issues.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Here is where Kotlin Multiplatform comes to the rescue. It allows you to implement a completely platform-native UI while sharing all the business logic layers beneath.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-102">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-103'
	>
	What is this sorcery?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	Kotlin Multiplatform is a feature of the Kotlin programming language that allows you to write code in Kotlin and then run it on several platforms:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-108">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-109'
	>
	<li>JVM (Android)</li><li>JavaScript (web)</li><li>Native – iOS, macOS, Windows, Linux</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	This article focuses mainly on Kotlin Multiplatform Mobile (KMM), which covers Android and iOS, but the fundamentals are the same for all the supported platforms.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-114">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-115'
	>
	How does it work?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	Kotlin Multiplatform converts the Kotlin code into code that can be used by individual platforms. It allows you to write common code to be used on all platforms, but also platform-specific code, which makes it a very flexible solution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-120">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-121'
	>
	The KMM app structure</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	Normally, we would have two separate apps, one for Android and one for iOS. These can be further split into multiple layers like the presentation layer, domain layer, data layer, etc. Kotlin Multiplatform Mobile introduces common code that can be shared between apps. The presentation layers (mostly UI) stay separate for each platform, while all the other layers can be shared. The shared part of the KMM app can be split again and include platform-specific code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-126"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-127">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-1-1400x545.webp				media='(max-width: 699px)'
				type=image/webp								height="545"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="623"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-129">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-130'
	>
	Each part of a KMM app also has its own testing package.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-132"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-133">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-2-1400x545.webp				media='(max-width: 699px)'
				type=image/webp								height="545"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="623"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-135">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-136'
	>
	Setting up a KMM project</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-138">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-139'
	>
	The easiest way to start a project with Kotlin Multiplatform Mobile is to use JetBrains Intellij IDEA and start a new Kotlin project from the multiplatform section.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-141"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-142">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-3-1400x718.webp				media='(max-width: 699px)'
				type=image/webp								height="718"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="821"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-144">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-145'
	>
	In the project structure on the right, you can see the separate Android and iOS apps and the shared module.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-147">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-148'
	>
	To kickstart your first KMM project, you can consider browsing the <a href="https://github.com/touchlab/KaMPKit">Touchlab’s KaMPKit repository</a>, forking the project, and starting from there.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-150"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-151">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-4-1400x858.webp				media='(max-width: 699px)'
				type=image/webp								height="858"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="981"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-153">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-154'
	>
	A newly created project has the structure shown above. The <em>androidApp</em> package is your standard Android app that includes the manifest, resource and main code directories. The largest part of this package should be the Android UI part (the Activities, Fragments, Views, etc.).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	The <em>iosApp</em> package has the standard iOS app structure, the same as it would be in Xcode. Most of the UI and ViewControllers are written here. There is no Kotlin code in this part, only Swift/Objective-C.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-160'
	>
	The <em>shared</em> part is where KMM shines. In that part, everything is written in Kotlin and controlled by Gradle. The <em>common</em> packages (<em>main</em> and <em>test</em>) should hold the most of the business logic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-162">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-163'
	>
	Sometimes, you need to write platform-specific code, usually when the implementation is impossible to share between platforms, for example, when access to the device’s hardware is required. In those cases, you can have a separate implementation in the Android part (main and test) and another one in the iOS part (main and test).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-165">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-166'
	>
	Sharing code between apps</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-169'
	>
	Adding the common part of the code to the Android app is not a problem because Android supports Kotlin. The shared code is simply included as a module. Things get slightly more complicated with iOS because it doesn’t support running Kotlin code directly. This can be solved with a plugin inside the shared gradle that uses CocaPods to generate an Objective-C Framework that is imported inside the iOS app. All you have to do is import the shared framework and use it in the Swift/Objective-C code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-171">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-172'
	>
	Expect and Actual</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-174">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-175'
	>
	The whole point in using Kotlin Multiplatform Mobile is to share as much code as possible, but each platform has its own API for accessing certain features like storage, bluetooth, network, etc., which means that at least some specific code will be needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-177">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-178'
	>
	To help with this issue, KMM uses two mechanisms, <code>expect</code> and <code>actual</code> declarations. The <code>expect</code> declarations can be found in the common package, while the respective <code>actual</code> declarations that respond to the expected ones are in the platform-specific package. The <code>expect</code> declarations feel similar to an interface, while the <code>actual</code> declarations are like interface implementations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-180"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-181">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-5-1400x311.webp				media='(max-width: 699px)'
				type=image/webp								height="311"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/11/kotlin-multiplatform-overview-5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="355"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-183">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-184'
	>
	Here’s an example for using the declarations to read from a Bluetooth LE characteristic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-186">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-187'
	>
	The package <code>shared/src/commonMain/kotlin/packagename/data</code> includes the following interface:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">interface ReadFromBleCharacteristicInteractor </span><span class="token">: </span><span class="token" style="color: #6f42c1;">BaseInteractor</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">ReadRequestData</span><span class="token">, </span><span class="token" style="color: #6f42c1;">ResponseData</span><span class="token">&gt;
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">class ReadFromBleCharacteristicInteractorImpl</span><span class="token">(
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">val </span><span class="token">bluetoothService</span><span class="token">: </span><span class="token" style="color: #6f42c1;">BluetoothService</span><span class="token">
</span></span><span class="line"><span class="token">) </span><span class="token">: </span><span class="token" style="color: #6f42c1;">ReadFromBleCharacteristicInteractor</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token" style="color: #d73a49;">suspend</span><span class="token"> </span><span class="token">fun invoke</span><span class="token">(input</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ReadRequestData</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ResponseData</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> 
</span></span><span class="line"><span class="token">bluetoothService</span><span class="token">.readFromBleCharacteristic</span><span class="token">(input)
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">interface BluetoothService </span><span class="token">{
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">fun readFromBleCharacteristic</span><span class="token">(readRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ReadRequestData</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Data</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">fun writeToBleCharacteristic</span><span class="token">(writeRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">WriteRequestData</span><span class="token">)
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token">class PlatformBluetoothService </span><span class="token">(
</span></span><span class="line"><span class="token">    context</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ApplicationContext</span><span class="token">
</span></span><span class="line"><span class="token">) </span><span class="token">: </span><span class="token" style="color: #6f42c1;">BluetoothService</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-191">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-192'
	>
	The implementation uses the <code>BluetoothService</code> interface, which has different API’s for Android and iOS. That is why the implementation of the interface is an <code>expect</code> class located in the <code>commonMain</code> package. The prefix <code>Platform</code> is not required, feel free to name the declaration however you want, but the word “Platform” might be useful to quickly identify the <code>expect</code>/<code>actual</code> declarations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-194">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-195'
	>
	The actual Android implementation is inside the package <code>shared/src/androidMain/kotlin/packagename/data</code> and it can use Android dependencies:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">android.bluetooth.BluetoothManager</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token">class PlatformBluetoothService </span><span class="token">actual </span><span class="token">constructor</span><span class="token">(
</span></span><span class="line"><span class="token">    context</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ApplicationContext</span><span class="token">
</span></span><span class="line"><span class="token">) </span><span class="token">: </span><span class="token" style="color: #6f42c1;">BluetoothService</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun readFromBleCharacteristic</span><span class="token">(readRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ReadRequestData</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Data</span><span class="token"> </span><span class="token">{ 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> android implementation of reading from BLE characteristic</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun writeToBleCharacteristic</span><span class="token">(writeRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">WriteRequestData</span><span class="token">) { 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> android implementation of writing to BLE characteristic</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-199">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-200'
	>
	Meanwhile, the iOS implementation is inside the package <code>shared/src/iosMain/kotlin/packagename/data</code> and it has access to the iOS platform dependencies:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">platform.CoreBluetooth.CBCentralManager</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token">class PlatformBluetoothService </span><span class="token">actual </span><span class="token">constructor</span><span class="token">(
</span></span><span class="line"><span class="token">    context</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ApplicationContext</span><span class="token">
</span></span><span class="line"><span class="token">) </span><span class="token">: </span><span class="token" style="color: #6f42c1;">BluetoothService</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun readFromBleCharacteristic</span><span class="token">(readRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ReadRequestData</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">ResponseData</span><span class="token"> </span><span class="token">{ 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> iOS implementation of reading from BLE characteristic</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun writeToBleCharacteristic</span><span class="token">(writeRequestData</span><span class="token">: </span><span class="token" style="color: #6f42c1;">WriteRequestData</span><span class="token">) { 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> iOS implementation of writing to BLE characteristic</span><span class="token">
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-206"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-204">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-205'
	>
	<code>Context</code> is needed in Android to get access to Bluetooth, but we cannot access Android <code>Context</code> in the common code, which is why we need another <code>expect</code> declaration:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">shared</span><span class="token" style="color: #d73a49;">/</span><span class="token">src</span><span class="token" style="color: #d73a49;">/</span><span class="token">commonMain</span><span class="token" style="color: #d73a49;">/</span><span class="token">kotlin</span><span class="token" style="color: #d73a49;">/</span><span class="token">packagename</span><span class="token" style="color: #d73a49;">/</span><span class="token">common 
</span></span><span class="line"><span class="token">expect </span><span class="token">class ApplicationContext
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">shared</span><span class="token" style="color: #d73a49;">/</span><span class="token">src</span><span class="token" style="color: #d73a49;">/</span><span class="token">androidMain</span><span class="token" style="color: #d73a49;">/</span><span class="token">kotlin</span><span class="token" style="color: #d73a49;">/</span><span class="token">packagename</span><span class="token" style="color: #d73a49;">/</span><span class="token">common 
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">android.app.Application</span><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token">typealias ApplicationContext </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Application
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">shared</span><span class="token" style="color: #d73a49;">/</span><span class="token">src</span><span class="token" style="color: #d73a49;">/</span><span class="token">iosMain</span><span class="token" style="color: #d73a49;">/</span><span class="token">kotlin</span><span class="token" style="color: #d73a49;">/</span><span class="token">packagename</span><span class="token" style="color: #d73a49;">/</span><span class="token">common 
</span></span><span class="line"><span class="token" style="color: #d73a49;">import</span><span class="token"> </span><span class="token" style="color: #6f42c1;">platform.UIKit.UIView</span><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token">typealias ApplicationContext </span><span class="token" style="color: #d73a49;">=</span><span class="token"> UIView
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	As you can see, the <code>expect</code>/<code>actual</code> mechanism can also be used with classes and typealiases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-214"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-212">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-213'
	>
	Similarly, it can be used for the following declarations:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-217"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-215">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-216'
	>
	<strong>Objects</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-219"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token" style="color: #d73a49;">object</span><span class="token"> </span><span class="token" style="color: #6f42c1;">HelloWorldObject</span><span class="token">          
</span></span><span class="line"><span class="token">actual </span><span class="token" style="color: #d73a49;">object</span><span class="token"> </span><span class="token" style="color: #6f42c1;">HelloWorldObject</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-222"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-220">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-221'
	>
	<strong>Functions</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-224"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token">fun helloWorld</span><span class="token">()
</span></span><span class="line"><span class="token">actual </span><span class="token">fun helloWorld</span><span class="token">() { </span><span class="token" style="color: #d73a49;">..</span><span class="token">. }
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-227"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-225">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-226'
	>
	<strong>Sealed classes</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token" style="color: #d73a49;">sealed</span><span class="token"> </span><span class="token">class HelloSealed </span><span class="token">{
</span></span><span class="line"><span class="token">    </span><span class="token">class World </span><span class="token">: </span><span class="token" style="color: #6f42c1;">HelloSealed</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">class Universe </span><span class="token">: </span><span class="token" style="color: #6f42c1;">HelloSealed</span><span class="token">
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token" style="color: #d73a49;">sealed</span><span class="token"> </span><span class="token">class HelloSealed </span><span class="token">{
</span></span><span class="line"><span class="token">    actual </span><span class="token">class World </span><span class="token">: </span><span class="token" style="color: #6f42c1;">HelloSealed</span><span class="token">()
</span></span><span class="line"><span class="token">    actual </span><span class="token">class Universe </span><span class="token">: </span><span class="token" style="color: #6f42c1;">HelloSealed</span><span class="token">()
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-230">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-231'
	>
	<strong>Interfaces</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-234"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token">interface HelloWorldInterface
</span></span><span class="line"><span class="token">actual </span><span class="token">interface HelloWorldInterface
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-235">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-236'
	>
	<strong>Vals and vars</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-239"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">expect </span><span class="token">val</span><span class="token" style="color: #d73a49;">/</span><span class="token">var </span><span class="token">helloWorld</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token">
</span></span><span class="line"><span class="token">actual </span><span class="token">val</span><span class="token" style="color: #d73a49;">/</span><span class="token">var </span><span class="token">helloWorld</span><span class="token">: </span><span class="token" style="color: #6f42c1;">String</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">HelloWorld</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-240">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-241'
	>
	Dependencies</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-243">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-244'
	>
	The dependencies for the shared module are managed by the gradle. If you have an Android background, it’s quite possible that most of your beloved libraries won’t work. Don’t worry, there are some really nice alternatives:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-246">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-247'
	>
	<li>For threading, instead of RxJava, you can use <a href="https://kotlinlang.org/docs/coroutines-overview.html">Kotlin Coroutines</a></li><li>For dependency injection, instead of Dagger there is the <a href="https://insert-koin.io/">Koin injection framework</a></li><li>For the database, instead of Room, you can use <a href="https://github.com/cashapp/sqldelight">SQLDelight</a></li><li>For networking, instead of OkHttp and Retrofit, you can use <a href="https://ktor.io/">Ktor</a>, with the OkHttp engine in the Android part</li><li>For quick access to key-value storage, you can use <a href="https://github.com/russhwolf/multiplatform-settings">Multiplatform Settings</a>, which give you access to Shared preferences on Android.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-249">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-250'
	>
	Since none of the Java libraries are allowed in the shared module, you can replace Java DateTime with Kotlin DateTime, which has almost the same API. If you are missing another library, check out <a href="https://github.com/korlibs/korlibs">Korlibs</a>, they offer many useful Kotlin libraries.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-252">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-253'
	>
	Defining dependencies</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-255">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-256'
	>
	The following example shows how to include the Ktor dependencies.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-258">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-259'
	>
	Inside the <code>shared/build.gradle.kts</code> file:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-262"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">sourceSets </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">commonMain </span><span class="token" style="color: #d73a49;">by</span><span class="token"> </span><span class="token">getting </span><span class="token">{
</span></span><span class="line"><span class="token">            </span><span class="token">dependencies </span><span class="token">{   
</span></span><span class="line"><span class="token">implementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">io.ktor:ktor-client-core</span><span class="token" style="color: #005cc5;">$ktor_version</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">) }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">commonTest </span><span class="token" style="color: #d73a49;">by</span><span class="token"> getting
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">androidMain </span><span class="token" style="color: #d73a49;">by</span><span class="token"> </span><span class="token">getting </span><span class="token">{
</span></span><span class="line"><span class="token">            </span><span class="token">dependencies </span><span class="token">{ </span><span class="token">implementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">io.ktor:ktor-client-okhttp</span><span class="token" style="color: #005cc5;">$ktor_version</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">) }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">androidTest </span><span class="token" style="color: #d73a49;">by</span><span class="token"> </span><span class="token">getting </span><span class="token">{
</span></span><span class="line"><span class="token">            </span><span class="token">dependencies </span><span class="token">{ </span><span class="token">implementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">io.ktor:ktor-client-mock</span><span class="token" style="color: #005cc5;">$ktor_version</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">) }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">iosMain </span><span class="token" style="color: #d73a49;">by</span><span class="token"> </span><span class="token">getting </span><span class="token">{ 
</span></span><span class="line"><span class="token">            </span><span class="token">dependecies </span><span class="token">{ </span><span class="token">implementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">io.ktor:ktor-client-ios</span><span class="token" style="color: #005cc5;">$ktor_version</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">) }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">iosTest </span><span class="token" style="color: #d73a49;">by</span><span class="token"> getting
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-263">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-264'
	>
	Each platform has its own main and test source set where the platform-specific dependencies are defined.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-268"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-266">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-267'
	>
	Pros &amp; cons</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-271"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-269">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-270'
	>
	Like any other <a href="https://infinum.com/blog/cross-platform-mobile-app-development-guide/">cross-platform solution</a>, KMM has its advantages and disadvantages. Here are some of them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-274"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-272">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-273'
	>
	Pros:</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-275">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-276'
	>
	<li><strong>Write once, run everywhere.</strong> Pretty straightforward, you write the code in Kotlin and you can run it on all the supported platforms.</li><li><strong>Flexibility.</strong> The <code>expect</code>/<code>actual</code> declarations allow you to jump to platform-specific code whenever you want.</li><li><strong>Familiarity with Kotlin, similarity to Swift.</strong> Onboarding to KMM is fairly easy for Android developers. There are some new libraries to get used to and you might have to slightly adapt your mindset when planning a feature’s architecture. Also, you have to forget about Java and Android imports in the common code, and seek alternatives. You can always go with <code>expect</code>/<code>actual</code> when there are none. iOS developers shouldn’t have a problem getting used to Kotlin since the syntax is very similar to Swift.</li><li><strong>New features in existing apps.</strong> Kotlin Multiplatform allows you to use the shared code as a module, so it can be easily added to an existing app for a new feature.</li><li><strong>100% native UI.</strong> Many cross-platform development approaches strive for the look and feel of the native UI, but there still might be some differences. Also, there is a learning curve for UI development in the cross-platform approach.</li><li><strong>Separation of the UI and the data layer.</strong> Kotlin Mutliplatform forces you to separate the UI layer from other layers of your app even more than in traditional apps. Android and iOS Imports are not allowed in the common code, so you have to structure your app without them, which is good practice for the future.</li><li><strong>Collaboration between Android, iOS and other teams.</strong> Kotlin Multiplatform strengthens the bond between teams working on the same app because they contribute to the same codebase and end up learning from each other.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-278">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-279'
	>
	Cons:</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-281">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-282'
	>
	<li><strong>Platform-specific implementation.</strong> While trying to share as much code as possible, you might end up writing a lot of platform-specific code, which can make the code less understandable and more complex.</li><li><strong>Threading.</strong> Using Kotlin and threading on native (iOS, desktop) requires you to use immutable objects, so either you use vals or you freeze the objects before switching threads.</li><li><strong>Initial learning curve for non-Kotlin developers.</strong> The syntax might be similar to other languages, but how Kotlin works under the hood is still different from other languages. Developers also need to learn about Gradle.</li><li><strong>No Java code shared.</strong> Currently, using Java utility libraries is still common in Android development, meaning that searching for Kotlin alternatives will take time and not everything is covered yet.</li><li><strong>Lack of documentation.</strong> KMM is a relatively new technology and its documentation is still a work in progress. Some libraries are already well-documented, but not all, especially for iOS. That community is still growing, as is the documentation, so it might take some time to find solutions to iOS problems. It’s much less of an issue with Android because the KMM development is very similar to native Android.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-286"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-284">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-285'
	>
	When to use KMM?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-289"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-287">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-288'
	>
	Kotlin Multiplatform Mobile is very versatile, but it doesn’t automatically mean it’s the right choice for the specific app you are building. You’ll need to assess your project and weigh in different factors. Here are some suggestions to help you decide:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-290">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-291'
	>
	<strong>Use KMM:</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-293">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-294'
	>
	<li>When you are building the app from scratch and want to keep the UI completely native, but there is some business logic that is not too platform-dependent (only storage and network requests).</li><li>When you are working with an existing app that needs a new feature, somewhat separated from the app’s other features. Since the UI is native, the app’s look and feel remains intact, while the business logic can be shared. The user most likely won’t notice any difference between features written in native code and those in shared code.</li><li>For building SDKs that are shared between multiple Android and iOS apps.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-296">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-297'
	>
	<strong>Don’t use KMM:</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-299">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-300'
	>
	<li>When there is a lot of communication with the hardware (internal sensors, bluetooth, NFC, externally connected devices, etc.). You might end up writing a lot of platform-specific code and wiring everything together. Making it work can be a hassle and just writing two separate apps would probably be easier, faster and ultimately result in a better product.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-302">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-303'
	>
	Looking ahead</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-305">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-306'
	>
	Though still relatively new, Kotlin Multiplatform can be a very useful solution in certain situations and save you the time and trouble of writing separate apps for different platforms. To see how it works in practice, you can try it out yourself on a simple project or just check out an example.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-308">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-309'
	>
	Kotlin Multiplatform is rapidly evolving and its community is constantly growing. It’s a feature you might want to keep an eye on.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/kotlin-multiplatform-overview/">More Platforms, Less Worries with Kotlin Multiplatform</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>