<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Romain Boisselle on Medium]]></title>
        <description><![CDATA[Stories by Romain Boisselle on Medium]]></description>
        <link>https://medium.com/@romainboisselle?source=rss-203270f15416------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*RKswPTtuHoXLY3Ap5-DulQ.jpeg</url>
            <title>Stories by Romain Boisselle on Medium</title>
            <link>https://medium.com/@romainboisselle?source=rss-203270f15416------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 09:50:16 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@romainboisselle/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[iOS development with JetBrains Fleet]]></title>
            <link>https://medium.com/kodein-koders/ios-development-with-jetbrains-fleet-fa83e5b0be96?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/fa83e5b0be96</guid>
            <category><![CDATA[jetbrains]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Sun, 26 Nov 2023 19:17:05 GMT</pubDate>
            <atom:updated>2023-11-28T07:05:06.577Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Farewell, AppCode; we’ve found a worthy replacement.</blockquote><p>This article is intended to demonstrate how to use <a href="https://www.jetbrains.com/fleet/">JetBrains Fleet</a> for the development of Swift/UI applications, including SwiftUI previews.</p><p>For those who may not know about JetBrains, it is an amazing company that builds tools for developers, such as IntelliJ IDEA or Kotlin. To me, JetBrains has always provided tools that exceeded my developer expectations, even when those tools are considered “not stable.”</p><p>A year ago, JetBrains announced <a href="https://www.jetbrains.com/fleet/">Fleet</a>, a brand new distributed and polyglot IDE. While many people saw it as just another VSCode IDE, I knew it would become more than that. Bringing collaborative work for remote developers and providing multiple language support out-of-the-box is a real game-changer. And if you’ve already tried a JetBrains IDE, you know that they are serious about developer productivity!</p><p>In the meantime, a year ago, they discontinued AppCode, an underrated IDE for working within the Apple ecosystem. AppCode was particularly helpful for developers who found it challenging to adjust to alternative IDE workflows, such as XCode.</p><p>With <a href="https://www.jetbrains.com/fleet/">Fleet</a>, you will experience easy code navigation, refactoring, collaboration, and support for a wide range of languages and project types, including SwiftUI applications.</p><p>Let’s be honest, you won’t completely escape from Xcode — there are still essential tasks like project configuration, signing, and package dependency management that require its user interface. However, for the majority of your coding sessions, you’ll find that you won’t need it anymore.</p><h3>Edit and run your iOS app from Fleet</h3><p>Let’s start by installing <a href="https://www.jetbrains.com/fleet/">Fleet</a> using the <a href="https://www.jetbrains.com/toolbox-app/">JetBrains Toolbox</a>. This is the easiest way to manage and upgrade your JetBrains IDEs in one place.</p><figure><img alt="JetBrains Toolbox" src="https://cdn-images-1.medium.com/max/1024/1*YxUqk7FFEN3hLN2HyF-7Fw.png" /><figcaption>JetBrains Toolbox — IDE version management</figcaption></figure><p>Once Fleet installed, you can either use your own SwiftUI project or clone the following GitHub project created for this article’s purpose.</p><p><a href="https://github.com/KodeinKoders/playground-fleet-swiftui">https://github.com/KodeinKoders/playground-fleet-swiftui</a></p><figure><img alt="JetBrains Fleet" src="https://cdn-images-1.medium.com/max/1024/1*pmLTT2cqDtaf6-Mpz7cYRg.png" /><figcaption>JetBrains Fleet IDE</figcaption></figure><p>Now, you can try to run the application by hitting the <strong>run button</strong> in the top right corner, or just use the ^R shortcut.</p><figure><img alt="JetBrains Fleet run window" src="https://cdn-images-1.medium.com/max/1024/1*2nMLXZOzaVBYh914bJhnzg.png" /><figcaption>JetBrains Fleet — Run dialog</figcaption></figure><p>At this point, it might work if you have recently opened XCode and/or built and run an iOS project. Otherwise, you will likely encounter an error, such as the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eiERRbjh3FGm8AYxPLg0bw.png" /><figcaption>JetBrains Fleet — Build error</figcaption></figure><p>This is certainly because your project’s environment is not ready to use any XCode toolchain. This can happen if you have never opened XCode or if you have just booted your Mac. The simplest solution is to open your project in XCode and build it <strong>once</strong> using CMD+B. Then you can close it and come back to Fleet.</p><p>Afterwards, you will be able to edit and run your iOS app from Fleet, even if you reboot your Mac!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vXIbBhDaYOjbRzzkeFHYzQ.jpeg" /></figure><h3>Add custom run configuration that works with Fleet</h3><p>Fleet allows you to define your own configuration to build and run your code. With Fleet, you can create multiple run configurations to target different schemes/devices without leaving the Fleet interface or going through XCode.</p><p>We can can create a run.json file inside a .fleet/ directory at the root of our project, such as the following example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2241b307cd78acb1bb8ea38fa25e12e3/href">https://medium.com/media/2241b307cd78acb1bb8ea38fa25e12e3/href</a></iframe><p>In this case, we define that our application needs to use the <strong>Xcode toolchain</strong>, that it should run on a<strong> iPhone 15</strong> simulator with <strong>iOS 17</strong>, using the <strong>debug</strong> configuration.</p><p>A nice thing here is, if your project’s environment is correctly detected via the XCode toolchain, the available destination devices will be auto-completable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7K13rDhUCIDs4WMkmrNrzw.png" /><figcaption>JetBrains Fleet — Run configuration</figcaption></figure><p>To find our different run configurations, simply click the run button or use the ^R shortcut.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UH_PJAPgvNeF_akYCFAuUw.png" /><figcaption>JetBrains Fleet — Run dialog</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*igDWB4WdMYkFAuTuuojvzg.png" /><figcaption>JetBrains Fleet — Application running</figcaption></figure><h3>Bonus: SwiftUI Preview with Fleet and InjectionIII</h3><p>One of the major benefits of developing with declarative UI frameworks like Jetpack Compose or SwiftUI is the ability to use tooling to preview your UI without having to build your application every time.</p><p>For this purpose you can use <a href="https://github.com/johnno1962/InjectionIII">InjectionIII</a>. Combined with Fleet, this project can be used as a file watcher, to hot reload SwiftUI changes, directly in your iOS Simulator.</p><p>Install it, directly from the <a href="https://apps.apple.com/us/app/injectioniii/id1380446739?mt=12?mt=12">Mac App Store</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*grHy78O2j9fRWtac9vwMWA.png" /><figcaption>Mac App Store — InjectionIII</figcaption></figure><p>Once installed, launch InjectionIII. You will find a small blue syringe icon in your menu bar. Click on it, then select “Open Project” to target the project you want to watch. This will allow it to inject changes into an iOS Simulator.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/322/1*xqeMpGM2FNL3h-jRGSho8g.png" /><figcaption>InjectionIII — Menu</figcaption></figure><p>Before running your application in the simulator and hot reload UI modification, you need to add <strong>debug</strong> specific code to your project. At the initialisation phase of the project, add the following if block.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a54109088ce2c901e3678c6f47f7c1fa/href">https://medium.com/media/a54109088ce2c901e3678c6f47f7c1fa/href</a></iframe><p>This code will include the InjectionIII binary in your iOS/MacOS app, but only for the debug configuration.</p><p>Likewise, in your SwiftUI preview code, you will need to make a slight change in order to define what you will be injecting into the Simulator.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e6a5adfe146f8262e3b166c21f593e3d/href">https://medium.com/media/e6a5adfe146f8262e3b166c21f593e3d/href</a></iframe><p>Now you can run your application onto an iOS Simulator. And when you will change some SwiftUI files, they will be injected directly inside this simulator instance, like in the following demonstration:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*S-CIlkiIPixSCE9DR8XN4w.gif" /></figure><p><a href="https://www.jetbrains.com/fleet/"><strong>JetBrains Fleet</strong></a> holds great promise for the future of IDEs. It is polyglot, collaborative, and expected to be much lighter than IntelliJ IDEA.</p><p>However, like any alpha product, there are some drawbacks. For instance, at the time of writing this article, you won’t be able to define breakpoints to debug your iOS application, and the fact that we depend on the Apple toolchain may break your workflow at some point.</p><p>However, the benefits are already evident. Even in its public preview, Fleet has excelled in every type of project I’ve worked on — whether it was Kotlin code, Android, backend, Kotlin Multiplatform projects, or platform-specific code such as pure Swift and SwiftUI projects. It has never failed me. This becomes even better when working with Kotlin Multiplatform code; being polyglot by essence, it allows us to seamlessly navigate between different technologies, from Kotlin to Swift in a glimpse. This is a real breeze.</p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform. Do not hesitate to visit our </em><a href="https://kodein.net/blog"><em>r</em></a><em>each out through our </em><a href="http://kodein.net/"><em>website</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fa83e5b0be96" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/ios-development-with-jetbrains-fleet-fa83e5b0be96">iOS development with JetBrains Fleet</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deploy your internal libraries on Github]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/kodein-koders/deploy-your-internal-libraries-on-github-e221d4a9a7a0?source=rss-203270f15416------2"><img src="https://cdn-images-1.medium.com/max/2353/1*InjKs6yaQUo_v__qJFdKAQ.jpeg" width="2353"></a></p><p class="medium-feed-snippet">In a previous tutorial, I explain how to configure and deploy your libraries to Maven Central. But, there are some libraries that that do&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/kodein-koders/deploy-your-internal-libraries-on-github-e221d4a9a7a0?source=rss-203270f15416------2">Continue reading on Kodein Koders »</a></p></div>]]></description>
            <link>https://medium.com/kodein-koders/deploy-your-internal-libraries-on-github-e221d4a9a7a0?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/e221d4a9a7a0</guid>
            <category><![CDATA[github]]></category>
            <category><![CDATA[bintray]]></category>
            <category><![CDATA[maven-central]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Tue, 27 Apr 2021 05:20:11 GMT</pubDate>
            <atom:updated>2022-06-22T09:47:14.960Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Building Kotlin/Multiplatform with Github Actions]]></title>
            <link>https://medium.com/kodein-koders/building-kotlin-multiplatform-with-github-actions-2478801d6d46?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/2478801d6d46</guid>
            <category><![CDATA[github]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[github-actions]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Thu, 15 Apr 2021 11:44:49 GMT</pubDate>
            <atom:updated>2022-06-22T09:51:32.450Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*SNLS-t1m0SwLciGCDoqBcA.png" /></figure><p>In a <a href="https://medium.com/kodein-koders/publish-a-kotlin-multiplatform-library-on-maven-central-6e8a394b7030">previous tutorial</a>, I showed you how to configure your Kotlin/Multiplatform libraries to be published on Maven Central. To go beyond a publication process we now need to automate things with a good CI/CD workflow. Let’s see how to do this with Github Actions.</p><p>As the <a href="https://github.com/kosi-libs"><strong><em>Kodein Open Source Initiative</em></strong></a><strong><em> </em></strong>libraries are hosted on <a href="https://github.com/Kodein-Framework">Github</a>, we felt that it was the best choice to use the Github Actions pipelines to test, build and deploy our libraries, as it is entirely integrated with every other part of Github.</p><p>Let’s start with the snapshot publication process, as it is fairly straightforward. Publishing snapshots on Maven Central has no more constraints than just being authenticated with your <em>Sonatype</em> account, and having your artifacts file names ending with the uppercased word SNAPSHOT. This means that you could literally upload anything in your staging repositories.</p><p>Here is a Github Actions script to upload a snapshot of a Kotlin/Multiplatform project:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/41c7ac097f1ff802076f92acc8243077/href">https://medium.com/media/41c7ac097f1ff802076f92acc8243077/href</a></iframe><p>In that example, we run the task publishAllPublicationToOss on Linux, Mac &amp; Windows, literally saying to publish every available targets onto the <strong><em>oss</em></strong> repository, which is the name we gave to it in our <strong>maven-publish</strong> configuration in our Gradle build script. This is not optimal, as every platform could upload shared targets like JVM, JS or even the Kotlin Multiplatform Metadata, but it’s simple, and it works!</p><p>Let’s now see how to deploy stable releases.</p><p>We have to discuss how we will be managing the unique staging repository we need. In fact, this is quite simple, and it is resume by this image:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jBjwilyz215Oagyb" /></figure><p>What we need is to create a staging repository, by using the sonatype API over HTTP. This step will generate a repository ID, that we use in later steps. In the <em>build-upload</em> matrix, we upload every artifact onto the same staging repository. Finally, In the <em>drop-or-release</em> job, depending on the success or failure of the <em>build-upload</em> matrix, we drop or release the staging repository.</p><p>Whatever happens in the build-matrix, we will always create a staging repository, and at the end drop or release that same repository, like in this failure scenario:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*y-Ivns0MR0KdECR_" /></figure><p>So, how do we manage consuming the sonatype HTTP API?</p><p>You could write Gradle tasks to create, drop or release the staging repositories. You could also use your favorite language / framework to automate everything. But, let me share our experience and choices.</p><p>We did consider using Gradle tasks, but Gradle would need to perform the full configuration of your project before being able to make only one or so HTTP requests. Sounds like we could do something more efficient. Our second thought was to use bash scripts, using curl to send HTTP requests, and <a href="https://stedolan.github.io/jq/">JQ</a> to parse JSON responses. Here is our very simple script that creates a staging repository with bash:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a9a3b531f5698e982478ea38ff559763/href">https://medium.com/media/a9a3b531f5698e982478ea38ff559763/href</a></iframe><p>This script needs 3 informations to create and retrieve a staging repository ID. Your credentials, username and password from your sonatype account, and the profile ID you want to use to publish your library. Note that you can have multiple profiles if you are allowed to send artifacts over different group ID.</p><p>If you don’t know your profile ID, you can get it through the sonatype API, here: <a href="https://oss.sonatype.org/service/local/staging/profiles">https://oss.sonatype.org/service/local/staging/profiles</a></p><p>The last command of our script will send our repository ID to the outputs of a Github Action job, to be consumed by future steps in our workflow. We have the same kind of script to drop or release the staging repository, in case of success or failure of our publication steps.</p><p>As nice and handy as these scripts are, using them in every project we have means downloading the proper .sh file, giving the system the right to execute it, and then run it with the right parameters, ending with numerous Github Actions jobs like this on every project:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c0a2eef15777bdb5b0d08cc1713ad7a/href">https://medium.com/media/4c0a2eef15777bdb5b0d08cc1713ad7a/href</a></iframe><p>This sounds cumbersome and hard to maintain at a larger scale, though.</p><p>Github provides a way to create automated tasks, called Actions. Those Actions can be written with JavaScript, or you can provide a Docker container configuration to be executed when you need. Therefore, we decided to create our own Action, with the help of our very good friend <a href="https://twitter.com/martinbonnin"><strong>Martin Bonnin</strong></a><strong> </strong>(<a href="https://github.com/martinbonnin">Github</a>). Our goal was to avoid the complexity of managing manual scripts in every project, and of course to share it with the community, giving the ability to anyone to handle their publication over Maven Central in an easy way.</p><p>Those Actions are available under the Github organisation <a href="https://github.com/nexus-actions"><strong>nexus-actions</strong></a>, so you can browse the code, copy them, and use them at your own convenience. Here is how to implement your release workflow with them:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a7bbb064e5576cdaae4bb5596f55cdc0/href">https://medium.com/media/a7bbb064e5576cdaae4bb5596f55cdc0/href</a></iframe><p>This job will be triggered only when a release is created on your Github repository. The first job will be to create the unique staging repository to upload all of our artifacts on, applying the action <a href="https://github.com/nexus-actions/create-nexus-staging-repo">nexus-actions/create-nexus-staging-repo</a>, with the proper parameters. We can now retrieve the output of the action, attach it to the outputs of our create-staging-repository job, and then use it in a later one.</p><p>Now, all we have to do is to publish our Kotlin/Multiplatform project with a simple job, that will grab the needed information from the Github secrets, and from the output of the job previously executed:</p><p>As you can see, this job will only be executed after the first one ends, as it needs it to finish. This job will run multiple times, once for every platform defined in the matrix. It is quite easy to consume outputs from an earlier job, we just need to invoke this job from our needed ones, and provide the correct name of the variable we want to use.</p><blockquote><em>This example, is really simple, if you are looking for more advanced use cases, you can check our </em><a href="https://github.com/kosi-libs"><strong><em>Kodein Open Source Initiative</em></strong></a><em> Github Actions, where we manage things like caching Gradle or Konan across builds, installing specific JDK or Android NDK, or even connected checks on the Android Emulator.</em></blockquote><p>Now, whatever is the result of this job, whether it fails or passes, we need to finalise our publication process, by either discard the already uploaded artifacts, or release the new version of our library.</p><p>Therefore, we need one last job that will always be executed:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/91e128e17bb618b21fa9102678d17f59/href">https://medium.com/media/91e128e17bb618b21fa9102678d17f59/href</a></iframe><p>Depending on the result of the build-upload job, only one step will be executed, drop or release. Both of them are based on a different action: either <a href="https://github.com/nexus-actions/drop-nexus-staging-repo">drop-nexus-staging-repo</a> or <a href="https://github.com/nexus-actions/release-nexus-staging-repo">release-nexus-staging-repo</a>, waiting for the same parameters : your credentials and the previously created repository ID.</p><p>The drop task will just ask to sonatype to delete the uploaded artifacts on that specific staging repository while the release task will close the staging repository and wait for the sonatype checks, checking all the requirements we had to comply with, and finally publish the brand new version to Maven Central, making it available for anyone to download.</p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform. Do not hesitate to visit our </em><a href="https://kodein.net/blog"><em>blog</em></a><em>, or our </em><a href="https://www.youtube.com/channel/UCbTrSXEB8flZ3XM9t3j4D8A"><em>Youtube channel</em></a><em> for more contents.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2478801d6d46" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/building-kotlin-multiplatform-with-github-actions-2478801d6d46">Building Kotlin/Multiplatform with Github Actions</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Publish a Kotlin/Multiplatform library on Maven Central]]></title>
            <link>https://medium.com/kodein-koders/publish-a-kotlin-multiplatform-library-on-maven-central-6e8a394b7030?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/6e8a394b7030</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[maven-central]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[maven-plugin]]></category>
            <category><![CDATA[sonatype]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Tue, 09 Mar 2021 15:02:47 GMT</pubDate>
            <atom:updated>2021-05-07T10:33:28.100Z</atom:updated>
            <content:encoded><![CDATA[<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKJRFChUbbZg&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKJRFChUbbZg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f069bfe70a66ec0f8528588ae5ee209/href">https://medium.com/media/1f069bfe70a66ec0f8528588ae5ee209/href</a></iframe><p>In <a href="https://medium.com/kodein-koders/create-a-kotlin-multiplatform-library-with-swift-1a818b2dc1b0">our last tutorial</a>, Salomon showed you how to create a Kotlin Multiplatform Mobile library. Now that we have some code ready to be used by the community, let me show you how to publish your future releases to Maven Central.</p><p>Before going into details about how to deploy your libs to Maven Central, I want to adress library developers who already have a library published on JCenter.</p><p>This tutorial is also for you!</p><p>Publishing on Bintray and JCenter was a choice most of us made, because it had less constraints and more flexibility. Now that they will be shutting down quite soon, we must migrate our publication workflow. Maven Central seems to be the right choice these days, but we need to deal with new requirements.</p><p>Where Bintray was giving us some latitude on what we could upload and publish, Maven Central has always been more restrictive. Indeed, every uploaded artifact needs to be accompanied at least by the following items:</p><ul><li>A bundle of the sources of the artifact</li><li>The documentation that goes with the artifact, in the JVM world this is the Javadoc.</li><li>A well formatted POM file. For those who are not familiar with Maven, this is the description of your project, with its name, its version, its dependencies, etc, in an XML format</li><li>And finally, every item needs to be signed to be accepted.</li></ul><p>Actually, these requirements are not that hard to fulfill, and Gradle provides almost everything we need to publish our artifacts smoothly, with 2 official plugins, <strong>maven-publish</strong> and <strong>signing</strong>.</p><p>But… I told you : almost!</p><p>When performing a publication, before being available on Maven Central, all your uploaded artifacts with <strong>maven-publish</strong> are generally stored and referenced in one staging repository that you need to validate as the final step of publishing. While this is true for standard JVM projects, this is not the case for Kotlin/Multiplatform ones.</p><p>As Kotlin/Multiplatform developers, you may know that you need two machines to build your project if you are targeting Windows and at least one other native platform. By doing so, each build will invoke the <strong>publish </strong>task that will<strong> </strong>implicitly create at least a different staging repository by platform. Why “at least’’? Because, while configuring our open source Kodein-Framework projects that often implies multiple modules or submodules, we found that a unique invocation of the plugin <strong>maven-publish, </strong>on a unique machine, ended up with a few 10ish implicit staging repositories created. That can become really cumbersome when managing multiple libraries.</p><p>This is why we need to control our publication workflow, by being able to publish one release from multiple builds on a single staging repository. We will see how in a minute, right after checking on some requirements.</p><p>Before diving into the configuration of your project, you will need to fulfil some requirements.</p><p>I won’t go into every detail, but I will give you some hints of what you need to publish on Maven Central.</p><p><em>If you already have a sonatype account, a verified repository and a GPG key pair, you can just move on to the next chapter.</em></p><p>As I just said, in regards to being able to publish your project to Maven Central, you will need to create a Jira account on sonatype and give them the possibility to verify the ownership of the group id you want to publish on. So, go to <a href="https://issues.sonatype.org/">https://issues.sonatype.org</a> and create your account.</p><p>After that, you should be able to open an issue, select &quot;New Project&quot; as the <strong><em>Issue Type</em></strong>, and let sonatype verify the ownership of your group id.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8ZT86yNBbCgqAiqIPWfmNw.png" /></figure><p>In my use case, I wanted the ownership of our group id <strong>org.kodein, </strong>where we will be publishing all the future versions of the Kodein-Framework.</p><p>After that, Sonatype will ask you to validate your ownership, either by adding a DNS record to your domain, or by creating a specific repository named after the ticket number if you own a Github organisation. Your repository should be ready to store and expose your artifacts within a few minutes. Verification is usually done automatically, but sometimes is manual and longer for security reasons.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yXq81bMh0Wo3GOb5tjAqjg.png" /></figure><p>Now you can upload whatever you want to your sonatype repository. But, if you want your artifacts to be available on Maven Central, they must pass through a validation process, which will check if these artifacts are correctly signed. In order to do so, you need to generate a GPG key pair.</p><p>While there are plenty of ways to generate your GPG keys, here is the quickest one. Note that on MacOS I use <a href="https://gpgtools.org/">GPG Suite</a> to handle my keys.</p><p>To create a new GPG key pair, run the command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/315/1*8y80aoZjLrDyQbQLRSj_9w.png" /></figure><p>With this, you just have to enter your name and email, a strong passphrase, and you’ll end up with a RSA key pair.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*U8SyU1N1VW2HfLNoiLdXig.png" /></figure><p>You can list your keys with the command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*3mzpYOSqSS-l8YUrLzqYDQ.png" /></figure><p>And, later on we will need to export our private key as “armored”, with the command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/548/1*2TYqctyidhoz3VsCLxm6vQ.png" /></figure><p>This will print your GPG private key in an ASCII format, surrounded with these key block delimiters.</p><p>I must warn you! You should never share your private key with anyone, under no circumstances. You should keep it somewhere safe, and do not lose it!</p><p>Now comes the fun part, configuring your Kotlin/Multiplatform project with vanilla Gradle. Let’s start by adding the necessary plugins to your configuration. Along with the Kotlin Multiplatform plugin we will apply the <strong>maven-publish</strong> and <strong>signing</strong> plugins.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94783ab14e0bc644964c38609abc1257/href">https://medium.com/media/94783ab14e0bc644964c38609abc1257/href</a></iframe><p>The <strong>maven-publish</strong> plugin will help us fulfill the sonatype publication requirements. Pointing the configuration to the sonatype OSS repository is quite simple. We can even put a condition onto the published version of our library, to upload them directly on the SNAPSHOT repository, which allows us to upload anything on your group ID, as long as its version ends with the uppercased word SNAPSHOT.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9e846af60441ae2504340034e67f17ed/href">https://medium.com/media/9e846af60441ae2504340034e67f17ed/href</a></iframe><p>As I said earlier, we prefer to upload our releases onto a unique staging repository to maximize our control over the publication workflow. Thus, we need to replace the release repo URL deploy/maven2 deploy/maven2 by deployByRepositoryId/$repositoryId, where the variable repositoryId can be set upward into Gradle properties, or via environment variables like in the following snippet:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9f895468f0fefed467c1479f3aa37fd0/href">https://medium.com/media/9f895468f0fefed467c1479f3aa37fd0/href</a></iframe><p>Note that, while doing so fixes the multiple repositories issue, this makes the deployment dependent on a specific environment variable.</p><p>What remains is to set up the credentials of your sonatype account, obviously not with hardcoded values, but as external resources. So here is a full snippet of the <strong>maven-publish</strong> plugin configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ed958d767e93c6fe8d1775703b8d9c1e/href">https://medium.com/media/ed958d767e93c6fe8d1775703b8d9c1e/href</a></iframe><p>Before singing every output item of our Kotlin/Multiplatform build, we need to add some extra configuration, so that the sonatype validation check passes. As I already said, Maven Central requirements are restrictive. In fact, along with our artifacts we also need to upload the related sources, docs and a POM file with a defined set of metadatas.</p><p>Sources are already packaged by <strong>maven-publish, </strong>but we will have to add the docs and the POM file. Here is an example of how to generate a POM file with the publication configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/284249a37e47abb15e5b48d357fba18a/href">https://medium.com/media/284249a37e47abb15e5b48d357fba18a/href</a></iframe><p>This means that for each Maven Publication task of our Kotlin/Multiplatform project, thus accompanying each target’s artifact, we will add a POM file with the required metadatas.</p><p>To provide some documentation to go with your artifacts, you can choose the easy way, like most of the libraries published on Maven Central, and “cheat” by adding an empty javadoc, with the following configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c39744b69cbd0d3fe7ee2801852187c/href">https://medium.com/media/5c39744b69cbd0d3fe7ee2801852187c/href</a></iframe><p>Or, you can configure Dokka, the documentation engine for Kotlin developed by JetBrains, and recently enabled for Kotlin/Multiplatform. Start by adding the dokka plugin to your configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3943e816e12f6b36193018fc862538f2/href">https://medium.com/media/3943e816e12f6b36193018fc862538f2/href</a></iframe><p>And now add the following snippet to your gradle configuration script:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/14537d1d2197079e33c383ec3ed3e7b1/href">https://medium.com/media/14537d1d2197079e33c383ec3ed3e7b1/href</a></iframe><p>This defines where the dokka task should put the generated documentation, and provides it to the javadocJar task, that will bundle it with a name like `artifact-javadoc.jar`. The delete Dokka Output Directory task will ensure that the documentation is up to date, by removing the old ones before regenerating it.</p><p>Now, like for the empty javadoc, just add the javadocJar task as an artifact of the MavenPublication tasks.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bed0d3cd6dbb3ec34eac4f1f82aea18e/href">https://medium.com/media/bed0d3cd6dbb3ec34eac4f1f82aea18e/href</a></iframe><p>We are almost there, ready to publish to Maven Central! The final rule that we need to validate is that every uploaded item needs to be signed. This is really trivial once you have your GPG key pair generated. You need to export your private key in an ASCII armored format with the following command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/548/1*2TYqctyidhoz3VsCLxm6vQ.png" /></figure><p>Save that output, and your GPG password, wherever it suits for your build process. In our case we put it in our Github’s secrets, being able to set them as environment variables in our Github Actions workflow.</p><p>So signing is now as simple as adding a few lines of gradle configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/32bfe45592dc74f18aa52a1bd1f57614/href">https://medium.com/media/32bfe45592dc74f18aa52a1bd1f57614/href</a></iframe><p>This defines how to retrieve the signatory configuration, by reading environment variables, and what should be signed. Here, we will be signing every output of all the publications tasks. You can now test your configuration locally by running the task `publishToMavenLocal`, and do not forget to set your environment variables.</p><p>Here is an example of the output of a publication for one target of the Kodein-DI library, with the kilb artifact, the sources, the javadoc, the pom file, and everyone of them is signed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/789/1*2tDcM_argF2--m9gkCl4jw.png" /></figure><p>You can now run the publish task on multiple machines to upload your artifacts, depending on your Kotlin/Multiplatform targets.</p><p>But, we are not done here. The next step would be to set up a CI/CD workflow to automate everything. We will cover that in a future tutorial, to see how to automate the publication of a Kotlin/Multiplatform project with Github Actions.</p><p>I really hope that you have learned something, and that this will be useful for you to share to the community your Kotlin/Multiplatform libraries on Maven Central.</p><p>Here is a playground project that contains everything you need to release your libraries on Maven Central. Link is also in the description.</p><p><a href="https://github.com/KodeinKoders/playground-publish-kmp-to-mavencentral/tree/main">https://github.com/KodeinKoders/playground-publish-kmp-to-mavencentral/</a></p><p>See you soon for more tutorials <a href="https://medium.com/kodein-koders">here</a> or on our <a href="https://www.youtube.com/channel/UCbTrSXEB8flZ3XM9t3j4D8A">KodeinKoders Youtube channel.</a></p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform.</em></p><p><em>Thanks to </em><a href="https://medium.com/u/9862bd834329"><em>Louis CAD</em></a><em> for reviewing this article.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6e8a394b7030" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/publish-a-kotlin-multiplatform-library-on-maven-central-6e8a394b7030">Publish a Kotlin/Multiplatform library on Maven Central</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dependency Injection for Kotlin/Multiplatform]]></title>
            <link>https://medium.com/kodein-koders/dependency-injection-for-kotlin-multiplatform-50a7221cc3a5?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/50a7221cc3a5</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Wed, 24 Feb 2021 12:50:21 GMT</pubDate>
            <atom:updated>2021-02-24T12:50:21.368Z</atom:updated>
            <content:encoded><![CDATA[<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FOEIMEVUC49I%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DOEIMEVUC49I&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FOEIMEVUC49I%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d724ba6758ff96cdcbef564c34a03086/href">https://medium.com/media/d724ba6758ff96cdcbef564c34a03086/href</a></iframe><p>In this article, we will see how to use a dependency injection library in your Kotlin/Multiplatform projects. I will walk you through the basics of the dependency injection pattern, and the materials we have at our disposal in a Kotlin/Multiplatform context, using the Kodein-DI library.</p><p>First, let me remind you why you should consider using dependency injection, and what are the benefits of a DI library. In software development, using dependency injection is the most popular technique to address the principle of separation of concerns. Its goal is to free objects of any responsibility but their original purpose. Let’s take an example of an application working with users, that is capable of retrieving data from an HTTP API, and also works offline with a local database. Here is the code we could write to make such an application:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f288098f7b6a7d0eeb60135a3db65702/href">https://medium.com/media/f288098f7b6a7d0eeb60135a3db65702/href</a></iframe><p>Here, the different classes are responsible for their functions’ behaviour, but they also are responsible for creating the objects they need to work properly.</p><p>A more idiomatic design would be to separate all the objects’ creation from their call site, by defining them as external resources, for instance as constructor parameters.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/86e50c300549c48417bf9dfb9bc1184a/href">https://medium.com/media/86e50c300549c48417bf9dfb9bc1184a/href</a></iframe><p>This removes the responsibility of creating dependencies, enables code reusability, and should help you mock and test your code easily.</p><p>Now, the simplest thing you could do is to manage your dependencies manually, to instantiate and inject them in a global context, accessible from anywhere in your application.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/03250b8996d82febef9c6fc61131e855/href">https://medium.com/media/03250b8996d82febef9c6fc61131e855/href</a></iframe><p>However, this comes with a cost. Testing the different units becomes a challenge, because our instances are tightly coupled with the Injector object. This means that we’ll have to know how to instantiate our objects and dependencies, and how they are used, before plugging everything manually. This is where a Dependency Injection library helps.</p><p>A DI library gives you the tools to define the dependency graph of your application, and will be able to dynamically inject the right dependency when needed. It also gives the ability to swap object’s instances, and replace them with different implementations in an easy and readable way, which removes a lot of pain points when testing your code.</p><p>So now, let’s see how to configure and use Kodein-DI, our favorite dependency injection library for Kotlin/Multiplatform.</p><p>Kodein-DI has never been easier to use and configure in KMPs. All you need to do is to define a dependency in the common source set of your Gradle build file, and you’re done. Thanks to the Gradle Metadata published along with all the Kodein-DI binaries, Gradle will be able to attach the right binaries for each target of your project.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c1cf80e22b6f2a551180cf17dbc162d/href">https://medium.com/media/8c1cf80e22b6f2a551180cf17dbc162d/href</a></iframe><p><em>NB: we highly recommend to use Gradle 6.0, or higher, which enables Gradle Metadata by default.</em></p><p>To see how to use Kodein-DI let’s take our last example, where every class receives its dependencies as constructor parameters.</p><p>In our common source set, we can define a DI container that will provide all the needed dependencies. Thus, we can bind straight instances, singletons or even constants.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7fe8d9d4cdea82ec05610e3ef6d066d0/href">https://medium.com/media/7fe8d9d4cdea82ec05610e3ef6d066d0/href</a></iframe><p>There are some other use cases where Kodein-DI can shine. For example, let’s say that you want to handle multiple databases, you could use tags to bind multiple instances of the DB object, and use those tags to inject the proper instance when needed.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7b8544a9fc509654087858795efe1d7b/href">https://medium.com/media/7b8544a9fc509654087858795efe1d7b/href</a></iframe><p>We are also able to bind more volatile objects through providers and factories. A factory will be executed every time the DI container asks for it. When using a factory you’ll have to pass arguments to the instance function to get its result.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fdb909595f1b1081dccf39cbefc9b5e6/href">https://medium.com/media/fdb909595f1b1081dccf39cbefc9b5e6/href</a></iframe><p>If you don’t want to bother managing your dependencies via your constructors, maintaining an API, a certain order in the parameters, and so on, you can pass around the DI container while writing your bindings. Therefore, you should be able to call every binding from that container.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e724c0ba5f2a4e57ecf31b03d0f158e3/href">https://medium.com/media/e724c0ba5f2a4e57ecf31b03d0f158e3/href</a></iframe><p>We can go further by using the `DIAware` interface. Every object that implements `DIAware` needs to override a `di` property as a `DI` container reference. This interface provides shortcuts to the container, like the `instance` delegate.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/66763106bc2726a9294dcae0f3e55e80/href">https://medium.com/media/66763106bc2726a9294dcae0f3e55e80/href</a></iframe><p>When declaring your bindings, all you have to do is to pass the DI container itself within your binding declaration.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4a279ee9a5fede09b424ec393fcb1d44/href">https://medium.com/media/4a279ee9a5fede09b424ec393fcb1d44/href</a></iframe><p>When working on bigger projects, We recommend to split your DI container into modules, to organise your code, or even be able to swap an entire block of dependencies. For example we could define a module for the app utilities, and one for the user business code, before importing them in a DI container.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fc2a2855e2470659cc0158a2e7c982b8/href">https://medium.com/media/fc2a2855e2470659cc0158a2e7c982b8/href</a></iframe><p>Now that we know how to bootstrap Kodein-DI in a Kotlin/Multiplatform project, let’s see how we can easily swap our bindings and test our code. With Kodein-DI, every dependency is resolved lazily when needed. This means that you don’t need to mock an entire module if its bindings aren’t useful for your test case.</p><p>For example, we can define a module <strong>“Mock/User”</strong>, that overrides our module <strong>“App/User”</strong> while importing them in a local DI container. Now our UserService object uses the mocks `MockUserRepository` and `MockUserApi` internally, meaning we can focus on unit testing the behaviours of UserService.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7cbfea10017b260462db231528e9cf19/href">https://medium.com/media/7cbfea10017b260462db231528e9cf19/href</a></iframe><p>In this article we explained what is the DI pattern and how to solve it with Kodein-DI, in a Kotlin/Multiplatform context. Now what remains is to use our business shared code within your favorite platforms. We will cover this in further videos for both Android and iOS, with some architectural approaches.</p><p>That’s it folks! Thanks for reading, see you next time for more content on Kodein-DI.</p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=50a7221cc3a5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/dependency-injection-for-kotlin-multiplatform-50a7221cc3a5">Dependency Injection for Kotlin/Multiplatform</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dependency Injection on Kotlin/Multiplatform — Part 3: iOS and Android]]></title>
            <link>https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-3-ios-and-android-da77879da1bb?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/da77879da1bb</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Wed, 09 Sep 2020 18:42:25 GMT</pubDate>
            <atom:updated>2020-09-09T18:42:25.309Z</atom:updated>
            <content:encoded><![CDATA[<h3>Dependency Injection on Kotlin/Multiplatform — Part 3: iOS and Android</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qjp37mMOBXdIdH-2" /><figcaption>Photo by <a href="https://unsplash.com/@karsten_wuerth">Karsten Würth</a></figcaption></figure><p>This article is part of a series about using dependency injection on Kotlin/Multiplatform:</p><ul><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-1-factorize-your-code-f299dd2a5d04">Part 1 : Factorize your code</a></li><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-2-test-and-build-b2e155c0824b">Part 2 : Test and build</a></li><li><strong>Part 3 : iOS and Android usage</strong></li></ul><p>In the first two parts, we saw how easy it is to use <strong><em>Kodein-DI</em></strong> to enhance your mobile app architecture in a <em>Kotlin/Multiplatform project, </em>and how to test all your business code once. Now it is time to write our mobile applications, for iOS <strong>and</strong> Android.</p><p>Continuing the previous example from <em>part 2</em>, we would have to implement a login form. So, we need to provide to the user a text field to enter a secret code, and a button to validate the form. On iOS, With <em>UIKit</em>, we would end with the following controller:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/72343303f512282ab8169648835b51ba/href">https://medium.com/media/72343303f512282ab8169648835b51ba/href</a></iframe><p>Before being able to use our <em>Kotlin/Multiplatform</em> library in Swift, we need to define its dependency on our project. We previously have defined the CocoaPods in our build script, thus we can import our <em>Kotlin Pod</em> by adding a <strong>Podfile</strong> to our iOS project:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bf1c349044ced8581fb1b87c28e34c35/href">https://medium.com/media/bf1c349044ced8581fb1b87c28e34c35/href</a></iframe><p>It is now as simple as adding an import in our Swift code to use our <em>Kotlin/Multiplatform</em> library, and plug our MVP upon our view:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/750ca6138e8a168dfdb1930aa5674ac3/href">https://medium.com/media/750ca6138e8a168dfdb1930aa5674ac3/href</a></iframe><p>Here we:</p><ul><li>import NBVCommon package</li><li>make the controller implement LoginView</li><li>inject the LoginPresenter with InjectorCommon defined in <em>part 1</em></li></ul><p>By using the lifecycle behaviors of the controller we can attach/detach the view from the presenter.</p><p>To act on presenter interaction, when login is success or failure, we have to implement the functions from LoginView, as if it was a regular Swift protocol.</p><p>As Kotlin has been available for Android for a long time now, it is really smooth to use a <em>Kotlin/Multiplatform</em> library here. So we can go a little further with <strong><em>Kodein-DI</em></strong>, as it has some specific modules to empower Android development. Assuming that we have published the <em>Kotlin/Multiplatform</em> library on Maven, all we need is to declare the dependency inside the Gradle configuration of our Android project:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/623a55f6f15e69211fefa9afdfed7acc/href">https://medium.com/media/623a55f6f15e69211fefa9afdfed7acc/href</a></iframe><p>You can see, that we also have a <strong><em>Kodein-DI </em></strong>module that will provide specific extensions for Android.</p><p>In Android it is not mandatory to define an Application, but using the <strong><em>Kodein-DI </em></strong>module for <em>AndroidX</em> can enhance your development experience.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a43e5105329c8d34ffe09857770b8d17/href">https://medium.com/media/a43e5105329c8d34ffe09857770b8d17/href</a></iframe><p>Now, let&#39;s get back to our login feature. For that, we write an Activity that implements DIAware , and by definition must override the di property. The delegate function di() comes from the <em>AndroidX</em> module of <strong><em>Kodein-DI. </em></strong>It looks for the nearest <em>DI container</em>, if there is one, in the application context, from Activity / Fragment hierarchy, until it find one.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d9a50710c78efe382b213690a64f61f7/href">https://medium.com/media/d9a50710c78efe382b213690a64f61f7/href</a></iframe><p>This allows us to inject the right presenter directly inside the Activity, with no pain</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b375068bfa8a4b0e7b478e8a5d824c97/href">https://medium.com/media/b375068bfa8a4b0e7b478e8a5d824c97/href</a></iframe><p>Sounds familiar? We just did the same as for iOS, but for Android! You can see that the native code for both platform stays really simple, and easy to maintain.</p><p>Of course, this is a quite simple example, but even in real world applications, the native code remains as stupid as possible. Indeed, all the business complexity has been develop from the beginning inside our <em>Kotlin/Multiplatform</em> library.</p><h4>Going Further</h4><p>In this series we have seen how to set up a MVP architecture with <strong><em>Kodein-DI</em></strong> in a multiplatform project, using the historical APIs of both mobile platforms.</p><p>Next, it should be interesting to move forward by using more modern tools, like the MVI pattern, made easier with SwiftUI and Jetpack Compose. We might talk about it in a future article.</p><h4><strong>Final though</strong></h4><p><strong><em>Kodein-DI </em></strong>is already a powerful library to use in <em>Kotlin/Mutiplatform </em>projects. However, there is still a lot to do to bring <strong><em>Kodein-DI</em></strong> as an ultimate tool for <em>Kotlin/Mutiplatform, </em>and we have plenty of ideas to do so<em>.</em></p><p>The more urgent subject are:</p><ul><li>Support for Swift, to be able to bind Swift objects smoothly</li><li>Support for coroutines, to inject asynchronous instances</li></ul><p>We also plan to provide more libraries for <em>Kotlin/Multiplatform</em> in a near future, stay tuned ;)</p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=da77879da1bb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-3-ios-and-android-da77879da1bb">Dependency Injection on Kotlin/Multiplatform — Part 3: iOS and Android</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dependency Injection on Kotlin/Multiplatform — Part 2 : Test and build]]></title>
            <link>https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-2-test-and-build-b2e155c0824b?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/b2e155c0824b</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Mon, 06 Jul 2020 12:00:19 GMT</pubDate>
            <atom:updated>2020-09-09T18:43:44.380Z</atom:updated>
            <content:encoded><![CDATA[<h3>Dependency Injection on Kotlin/Multiplatform — Part 2 : Test and build</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*Za_X2oTz9afo2b3s" /><figcaption>Photo by <a href="https://unsplash.com/@jeffkingla">Jeff King</a></figcaption></figure><p>This article is part of a series about using dependency injection on Kotlin/Multiplatform:</p><ul><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-1-factorize-your-code-f299dd2a5d04">Part 1 : Factorize your code</a></li><li><strong>Part 2 : Test and build</strong></li><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-3-ios-and-android-da77879da1bb">Part 3: iOS and Android</a></li></ul><p>In the first part we saw how to configure our <em>Kotlin/Multiplatform</em> project with <strong><em>Kodein-DI</em></strong>, then we have defined our architecture and our common business code. Now we need to test our code, once, before building it and using it on both mobile platforms ; <em>iOS </em>and <em>Android</em>.</p><p>Before being able to run tests upon our Kotlin code, we will need to configure our Gradle project depending on the platform we are targeting. As we are making a <em>Kotlin/Multiplatform</em> project, we certainly need to define test dependencies for our common code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/25cd8ecbccbce7ab685d5fdad9303220/href">https://medium.com/media/25cd8ecbccbce7ab685d5fdad9303220/href</a></iframe><blockquote>You can see that in <em>Kotlin/Multiplatform</em> project test dependencies are like normal dependencies, as they match to specifics source sets.</blockquote><p>The power of <em>Kotlin/Multiplatform</em> is to allow us write code once, and then test it once, in the commonTest source set. But, along the way, you will probably need to interact with some platform specific APIs, thus you would also need to include platform specific testing dependencies, like for the JVM:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c47549849aa745f2d5a611c11283b43/href">https://medium.com/media/8c47549849aa745f2d5a611c11283b43/href</a></iframe><p>For the Native source sets we do not need to define test dependencies, as they are built-in into kotlin-test, already added in the common source set.</p><p>This article is not about what you need to test and why, but how to use the dependency injection pattern, with <strong><em>Kodein-DI</em></strong>, to test your Kotlin/Multiplatform code, before building and using your library.</p><p>If you have read the first part, you nay have seen me coming, as I intentionally used interfaces and separate <strong><em>Kodein-DI</em></strong> modules to make my code independent, swappable and testable, without having to mock or fake the whole application for every test.</p><p>Let’s take the previous example from our first article. The login module is composed of four bindings:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ad226e78c91ae44451f192ca34819cf/href">https://medium.com/media/9ad226e78c91ae44451f192ca34819cf/href</a></iframe><p>Where TokenRepisotry, AuthApi and Login.Presenter are interfaces, and their implementation have the following relations:</p><ul><li>AuthApiImpl needs an instance of some TokenRepository</li><li>LoginPresenterImpl needs an instance of some AuthApi</li></ul><p>To test this architecture we will have to import the login module, and override some of the binding to fake their behaviour, in order to test each pieces of our code, independently. Let’’s see how we can do this.</p><p>As an example, we will be testing the LoginPresenterImpl. In order to do that, we have to fake the behaviour of the TokenRepository and AuthApi, to control their flow. Here are two implementations, for both of them, one considering that login in is a success and one considering it&#39;s not. We will also add, a fake view to check the right behaviour of the Presenter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/790bb166644fde6e5212958378293720/href">https://medium.com/media/790bb166644fde6e5212958378293720/href</a></iframe><p>Now, we have to declare a <strong><em>DI</em></strong> container that will be carrying our fake implementations:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0a492cadd3056c42b4131ed6af998d5/href">https://medium.com/media/f0a492cadd3056c42b4131ed6af998d5/href</a></iframe><p>This code defines a container that is meant to be used just for our tests, with the smallest scope, to avoid unpredictable behaviours.</p><p>The following line imports the loginModule from our library. We specify that the current container can override existing dependencies of this module.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26bb93c620156eea01606a0d673ad42b/href">https://medium.com/media/26bb93c620156eea01606a0d673ad42b/href</a></iframe><p>Now, we just need to override the existing bindings for AuthApi and TokenRepository:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ec4543a0a2d91b5b84d674df4f635b6/href">https://medium.com/media/3ec4543a0a2d91b5b84d674df4f635b6/href</a></iframe><p>And finally, this will allow us to instantiate a new TestLoginView every time we need one:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5372f1f751d54ccd388663bc0975ec07/href">https://medium.com/media/5372f1f751d54ccd388663bc0975ec07/href</a></iframe><p>This <strong><em>DI</em></strong><em> </em>container can be use in our test class by implementing the DIAware interface. It will help us to write our test, avoiding to call the <em>DI </em>container every time we need it, by calling by instance() instead of by loggedInContainer.instance(). This is possible because we will be overriding the di property, from DIAware.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4532c87eb64620c5f6f148633a66ab51/href">https://medium.com/media/4532c87eb64620c5f6f148633a66ab51/href</a></iframe><p>Swapping our fake object is now really simple, for example here is another <strong><em>DI</em></strong> container that will help us testing when the user is not logged, or when the API calls are failing:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/10168397de29ee39f5cf57707958f3e4/href">https://medium.com/media/10168397de29ee39f5cf57707958f3e4/href</a></iframe><p>Now that we have our multi-platform code, tested, we can confidently build our Kotlin/Multiplatform library before using it on <em>iOS</em> and <em>Android.</em></p><p>While building a library for <em>Android</em> is kind of straightforward, for <em>iOS</em> it hasn’t always been that simple.</p><p>Remember, to configure our <em>Kotlin/Multiplatform</em> project we need to define special cases for <em>iOS</em>, depending on the SDK we are targeting, either iOS ARM64 devices or the iOS x64 simulator. Even if we are able to build a fat universal .framework , this can lead us to managing intermediate source set, that was not trivial to use, until Kotlin 1.4-M2.</p><p>Back to the point, today there is two path for building <em>Kotlin/Multiplatform</em> library for <em>iOS</em>.</p><p>In the early versions of <em>Kotlin/Multiplatform</em> we had to specify a Gradle task to create a .framework file, that could be added to your Xcode configuration manually. Here is the task to add in your <em>build.gradle.kts </em>file.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c95174a8194022e6acef274d49cdbce/href">https://medium.com/media/1c95174a8194022e6acef274d49cdbce/href</a></iframe><p>For some convenience, here we also add the dependency on packForXcode, thus the framework would be built when building our entire project with:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ea291e64976fc5b53356432799ed114c/href">https://medium.com/media/ea291e64976fc5b53356432799ed114c/href</a></iframe><p>However, iOS developer have tools too! <a href="https://cocoapods.org/">CocoaPods</a> is a dependency management tool for Swift and Objective-C projects, and JetBrains has been kind enough to develop a Gradle plugin, that gives us the ability to provide our <em>Kotlin/Multiplatform</em> library to iOS developers, without breaking their habits. To do so, add the plugin org.jetbrains.kotlin.native.cocapods to your gradle configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fc93bb15462d21cd229c51974e1cc1e1/href">https://medium.com/media/fc93bb15462d21cd229c51974e1cc1e1/href</a></iframe><p>Then, wee need to define the <em>cocoapods </em>configuration like below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/13be5061fdca69b62e5c5911091ae441/href">https://medium.com/media/13be5061fdca69b62e5c5911091ae441/href</a></iframe><p>Then running the following Gradle task will make the library available for <em>cocoapods:</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3f04cebd1504c6004500d413a6e12eb1/href">https://medium.com/media/3f04cebd1504c6004500d413a6e12eb1/href</a></iframe><p>(we will see what is the output and how to use it in the next article).</p><p>As I said before, building our app for Android is pretty straightforward, nowadays. For this example, we will just build a .jar. Nevertheless, you still can build an .aar with <em>Kotlin/Multiplatform</em> by including an Android SDK dependency into the project configuration.</p><p>To use our <em>Kotlin/Multiplatform </em>library on Android, we need to publish it on a package repository, like <em>Maven</em> or <em>JCenter. We can use the Gradle plugin</em><em>maven-publish</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3be1f87a50b96cb1738fca88edc27fce/href">https://medium.com/media/3be1f87a50b96cb1738fca88edc27fce/href</a></iframe><p>And then call the corresponding task:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1efd4e77f6817e54437fd112cafd399a/href">https://medium.com/media/1efd4e77f6817e54437fd112cafd399a/href</a></iframe><p>That all for this one! Next time, we see how to use our Kotlin/Multiplatform library on <em>iOS </em>and <em>Android.</em></p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b2e155c0824b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-2-test-and-build-b2e155c0824b">Dependency Injection on Kotlin/Multiplatform — Part 2 : Test and build</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dependency Injection on Kotlin/Multiplatform — Part 1: Factorize your code]]></title>
            <link>https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-1-factorize-your-code-f299dd2a5d04?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/f299dd2a5d04</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Mon, 22 Jun 2020 13:00:08 GMT</pubDate>
            <atom:updated>2020-09-09T18:44:25.368Z</atom:updated>
            <content:encoded><![CDATA[<h3>Dependency Injection on Kotlin/Multiplatform — Part 1: Factorize your code</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*67kDRQPVt2vpt4ID" /></figure><p>This article is part of a series about using dependency injection on Kotlin/Multiplatform:</p><ul><li><strong>Part 1 : Factorize your code</strong></li><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-2-test-and-build-b2e155c0824b">Part 2 : Test and build</a></li><li><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-3-ios-and-android-da77879da1bb">Part 3: iOS and Android</a></li></ul><p><em>Kotlin/Multiplatform</em> is certainly on the 2020’s list of programming trends. For sure, it’s a very nice technology, and it is now pretty mature. However, when starting using something new, it’s also convenient to have a bunch of tools that make our day to day job easier. <em>Kotlin/Multiplatform</em> journey is at its beginning, when it comes to tooling, there are some few, but there are still some topics no covered yet, and we are excited to see what’s coming in the next few months.</p><p>Until then, this is the first article of a series, that will guide you through the use of our <em>Kotlin/Multiplatform</em> Dependency Injection library: <a href="https://github.com/Kodein-Framework/Kodein-DI"><strong><em>Kodein-DI</em></strong></a><em>.</em></p><p>In this part, we will see what we’ll be building, how to configure your <em>Kotlin/Multiplatform </em>project<em>, </em>and how to use<em> </em><strong><em>Kodein-DI</em></strong><em> </em>in this particular use case<em>.</em></p><p>As with my wife we are close to having our second child, I have decided to find some time to build an app for our friends and families to bet on the name, the date and some other data regarding the birth of the new kid 😃</p><p>Here the data classes of the app:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c827cfe408cb966f0e26ecf13e62b49/href">https://medium.com/media/0c827cfe408cb966f0e26ecf13e62b49/href</a></iframe><p>So the idea is quite simple. We need to provide an app to enter those prognostics information and send them to a server. But, among our friends and families, there is both <em>Android</em> and <em>iOS</em> devices… Let’s try to factorize and test our business code in one place before using it on native platforms.</p><p>I am moving fast over the configuration of our <em>Kotlin/Multiplatform</em> project, as many resources have already covered this part:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e64315a97ccd4ca1b2f5d4519461eb5e/href">https://medium.com/media/e64315a97ccd4ca1b2f5d4519461eb5e/href</a></iframe><p>What will matter to us, is how do we manage dependencies for <em>Kotlin/Multiplatform</em> projects, and more precisely for <em>Kodein-DI.</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0584e18af6b12f0cca6e3cd59fa53398/href">https://medium.com/media/0584e18af6b12f0cca6e3cd59fa53398/href</a></iframe><p>Thanks to the <em>Gradle Metadata </em>feature<em>,</em> we do not have so much to do while targetting different platforms, but just declaring the use of <strong><em>Kodein-DI</em></strong> in the <em>common source set, </em>as long as you are using<em> Gradle 6+</em>.</p><p>In fact, when we build <strong><em>Kodein-DI,</em></strong> on <em>MacOS </em>for example<em>, Gradle</em> will produce binaries for each targetted platform, like MacOS / iOS / JVM / JS. But, it will also produce some files that are carrying references on which binaries are needed depending on the target. So, in the case of androidMain , Gradle will get org.kodein.di:kodein-di-jvm .</p><blockquote>Note: there are Android-specific <strong><em>Kodein-DI</em></strong> modules that we will cover in a future part.</blockquote><p>As we do not want the entire earth to be able to vote, I put a simple PIN-based authentication. This auth is verified by the server and returns a token, stored on the device. Here is the definition:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c08d65dc1f506b35e4b6cd958d1fa45e/href">https://medium.com/media/c08d65dc1f506b35e4b6cd958d1fa45e/href</a></iframe><p>What&#39;s important here is the fact that most of the classes have interfaces. That way, implementations will be swappable with fake objects for testing, by using <em>Kodein-DI</em>.</p><p>To interact with the UI, thus the native code, I’ve chosen to use the <em>MVP</em> pattern, as I find it simple to grasp and to use for my use case. Thus, I have 2 interfaces, one for the <em>Presenter</em> and one for the <em>View</em>, that should be implemented or used by my native code somehow.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d15ee71a7738e0a73280c3fd4d2353f/href">https://medium.com/media/5d15ee71a7738e0a73280c3fd4d2353f/href</a></iframe><p>The Login.Presenter can receive instruction to authenticate the user with a secret PIN or to check the current state of the authentication.</p><p>The Login.View can respond to the UI with a onLoginSuccess function, but also with a onError, available from its parent interface BaseView.</p><p>You may have noticed that LoginPresenterImpl is implementing the interface DIAware. This provides a global approach for the class to use the dependency injection. Because of the interface, we can smoothly retrieve our dependency bindings as delegated properties, using by instance(). Doing so, the AuthApi and TokenRepository should be retrieved seamlessly, without the need to know how to instantiate them, at call-site.</p><p>This article is all about managing our dependency injection while using <em>Kotlin/Multiplatform, remember?</em>. So, let’s see how to define our dependencies.</p><p>To be able to test efficiently my business code, I decided to split concerns in modules. <strong><em>Kodein-DI</em></strong>&#39;s modules provide a way to extract our bindings in separated objects, avoiding one big central DI container, containing every binding of our application. Those modules can be imported side by side in a global container.</p><p>With this approach, I should be able to test atomically my code, or even swap an entire module if needed. Here is my <strong>login</strong> module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2dc6b220316aafd255cedade351c4ebd/href">https://medium.com/media/2dc6b220316aafd255cedade351c4ebd/href</a></iframe><p>So you’ve read so far, cool! Here is another example, based on the <em>Participant API,</em> used to give to the users the ability to send prognostics, change them, and see what they already have sent.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/258dd2fef9a76af3c7e4297831d59275/href">https://medium.com/media/258dd2fef9a76af3c7e4297831d59275/href</a></iframe><p>And here is the corresponding <strong><em>Kodein-DI</em></strong> module definition:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7a7903596ff91994b5e62a6cdcbf2f76/href">https://medium.com/media/7a7903596ff91994b5e62a6cdcbf2f76/href</a></iframe><p>Now that we have defined our APIs and our DI modules, we will need to set on a dependency injection container, that will carry every binding that we would be using in our application.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a8e0fe7f875c3824e2379568e0945882/href">https://medium.com/media/a8e0fe7f875c3824e2379568e0945882/href</a></iframe><blockquote>Note: We didn’t talk about the database layer, we will certainly do in some next articles ;)</blockquote><p>So, every module is imported in a global container. Usable in any native code, almost…</p><p>At the moment, <strong><em>Kodein-DI</em></strong><em> (v7.0) </em>is <em>Kotlin/Multiplatform</em>, but, as it will mainly be a dependency for another <em>K/M</em> project, the API would less usable from non-kotlin native code, like <em>Swift</em>. Indeed, <em>Swift</em> does not support things like delegation properties or reified parameters, making the use of instance&lt;T&gt;() function impossible. So, for now, the solution is to give the ability to swift to call out our dependencies through facades:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26e471df7fb5b320b49aca7f5f344ed9/href">https://medium.com/media/26e471df7fb5b320b49aca7f5f344ed9/href</a></iframe><p>Don’t worry, we are working on something that will make <em>Kodein-DI </em>as easy to use from Swift than from Kotlin 🙂</p><p>Here we have defined how to bootstrap our <em>Kotlin/Multiplatform</em> project using <strong><em>Kodein-DI</em></strong><em>. </em>Next time we will see how we can test our code and how to bundle .jar and .framework to be used on <em>Android</em> and <em>iOS</em>.</p><p><em>This article is brought to you by </em><a href="https://kodein.net/"><strong><em>Kodein Koders</em></strong></a><em>, a European service &amp; training provider focused on Kotlin &amp; Kotlin/Multiplatform.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f299dd2a5d04" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kodein-koders/dependency-injection-on-kotlin-multiplatform-part-1-factorize-your-code-f299dd2a5d04">Dependency Injection on Kotlin/Multiplatform — Part 1: Factorize your code</a> was originally published in <a href="https://medium.com/kodein-koders">Kodein Koders</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kodein-DI v7.0 is out!]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/kodein-koders/kodein-di-v7-0-is-out-c1b388ce80d?source=rss-203270f15416------2"><img src="https://cdn-images-1.medium.com/max/1600/1*XwGtGza4woDwXj3VBlVx1A.png" width="1600"></a></p><p class="medium-feed-snippet">Kodein-DI new release overview.</p><p class="medium-feed-link"><a href="https://medium.com/kodein-koders/kodein-di-v7-0-is-out-c1b388ce80d?source=rss-203270f15416------2">Continue reading on Kodein Koders »</a></p></div>]]></description>
            <link>https://medium.com/kodein-koders/kodein-di-v7-0-is-out-c1b388ce80d?source=rss-203270f15416------2</link>
            <guid isPermaLink="false">https://medium.com/p/c1b388ce80d</guid>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[kodein]]></category>
            <category><![CDATA[dependency-injection]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Romain Boisselle]]></dc:creator>
            <pubDate>Wed, 03 Jun 2020 13:13:17 GMT</pubDate>
            <atom:updated>2020-06-15T09:06:30.082Z</atom:updated>
        </item>
    </channel>
</rss>