Kotlin MP: Into the Multi-Verse
Srivastava, Nishant
Kotlin Multiplatform is the new kid on the cross-platform block. The approach although is very different from what you have seen in the past. The new approach utilizes Kotlin Native to compile Kotlin language to native binaries for specific target platform which can run without a virtual machine. Thus enabling simplified code sharing across multiple platforms. In this talk, you will be introduced to Kotlin/Native and demonstrate how to build a Kotlin Multiplatform app that runs on both iOS and Android using shared Kotlin code.
 Yeah, everyone again, thank you for coming. Don't forget to yeah, help your chair when you leave the room. It's really nice. Don't pass in front of the camera over there. And we still have Japanese licenses. So open for request. Then I'm happy to introduce Nishon. He is going to talk about Kotlin MP into the multiverse. So please give him a big round of applause. Okay, hello everyone. You can all hear me right at the back also. I hope okay great. Thank you all for coming to this talk. So the idea about this talk basically came through because I was trying to like find out ways of working with Kotlin multi-platform as like people been talking about it and a lot of things are going around this. So I eventually started like trying out how I can get this to work. Turns out it's not as easy as we think it is. So that's how this talk came to be. So what I'm going to be doing here is I'm going to try to at least convince you all to understand how Kotlin multi-platform in general is working and what's doing. And then I'm also going to show you how you can actually get a working application for Android and iOS because it's not as simple as you think. Like you just fire up an ID and it works. No, it's not that. That's what I will show you. So let's start with that. So I said Kotlin MP. What does that actually mean? As you would have guessed, it's basically Kotlin multi-platform. There's no formal definition for this like what exactly it is. So I came up with my own from what I understood. Basically we are utilizing Kotlin language to build for these multiple target platforms. I'll get to what target platforms are in a few minutes, which enables code sharing while being as flexible as you can be. So I'm going to break this down because like a full statement, okay, there's a lot of things being said here. In general Kotlin multi-platform is like an open source tool or I should say plugin. That's available. It uses Kotlin as your common code here. Also it's targeting multiple platforms. The code sharing is specifically happening for data domain and presentation layer. The different thing about it is that it integrates with the existing native platforms. So it leverages the native capabilities of the platform when it is required. It's not that you are specifically forced to use them. It's more a choice on you when you need to use them. You will go ahead and use them. It's optional as it's not opinionated. It ties into the same point as above. It will not ask you to specifically use a certain pattern. It will not ask you to do some sort of like trickery or like use a different language to work with. So it's basically trying to help you as much as it can while giving you all the choices. But the question here is why? Why are we even trying to do this? So from what I understand is that up till now there have been like all these different possibilities that we could use Kotlin for. You could use Kotlin for generating JavaScript code and then you could use Kotlin for generating the JVM base code, the byte code, right? And then Kotlin native came into place and that allowed people or at least the Kotlin tool chain to generate more target platform specific code. So you can think of something that's more near to the machine level code here. And the second point that's very important is that existing solutions are very opinionated. I'm looking at Flutter, React Native and then you also have Xamarin. Obviously people have tried CC++ in the past too. All of these are very opinionated in the sense that they force you to use a certain pattern. Flutter would basically ask you to use first of all a different language. So you start from a different stack and a different language. At the same time it tells you that you cannot use the platform widgets because it is going to be drawing all the widgets for you on the screen, right? So those kind of like opinionated versions exist and that's why Kotlin native is Kotlin multi-platform now is something that's more considered. It's something like this, like we have a situation where it's a dilemma of the mobile app development right now. If you want to develop a native app for each device and maintain several projects, this is what it looks like on the right. And then you use a unique framework like say Phone Gap and then App Accelerator like in the past or you could use Flutter or even React Native. You end up building something that is limited in functionality. Why am I saying that? Because there have been companies who have tried this in the production. Like for example, you know, Airbnb tried React Native and then they pushed back to going to native again. Dropbox tried CC plus us for their cross-platform capabilities in the application but they also went back to native because there's certain things that you cannot do when you're trying to share most of the code across platforms. So let's dive into the multi-verse of platforms here or target platforms. That's the technical word for it. The way I understand target platform, I think this was explained in the last talk a little bit. The point here is that I understand it as compiled artifacts to be consumed by specific platform. So say for example, when we are considering Kotlin JVM, the artifact that will be consumed by the platform would be jar and AR files, right? This can be consumed by Java, by Android, by Spring Boot. If you have Kotlin JS, it's going to be generating JavaScript code which you can bundle it up and push it with say JavaScript, React, or Node. And then there comes the Kotlin native part which enabled more possibilities where you have ability to generate code that is native to the ARM platform or CPU in general that you can push it with the Android and DK. You have iOS version. The iOS X64 by the way is the emulator. Similar you have for TVOS. X64 is again emulator version. WatchOS. X86 is again for emulator. And the other versions are when you want to run them on the device. And then you have more where you have the Linux ARM version, the MIPS version for the same, MacOS, X64, MINGW which is basically for Windows, and then the WSM32 which is for WebAssembly. That's what Kotlin native is allowing you to target now because it's generating artifacts that can be consumed by code that's running on this platform. So this brings me to the next part here because it's not just the target platform, it's also about code sharing. So when we say code sharing, we are actually talking about more related to the data layer in general, right, where you can put your networking code that can be shared across multiple platforms. You can put caching. You can put repositories. You can even put something like a presentation layer which is common on Android side. You have view models and presenters, controllers. And then there's the domain layer where you can put use cases, entities, and the interactors. What is also important here is that we are not talking about the UI at all. Now, why we are not talking about the UI because Kotlin native in general doesn't even care about UI. Each of these platforms that exist have their own way of representing UI. iOS has its own version. Android has its own version. Say, example, Linux has its own version, and they all do their job pretty well. So what the native is basically saying is that we're going to build an artifact for you. You plug that into your application, build the UI on your own, and then use this whole code, right? So this is the artifact that has been generated on all of these different platforms is what is shared, but the UI is still native. This is more or less on the side of just making sure that the UI gets updated pretty frequently, right? But your business logic anyway stays the same. So you want to share your business logic mostly and not the UI. UI can change whenever you want based on whatever technology you use. Even say, for example, on iOS, we were developing a lot of like UI with, say, you controllers and other stuff. Now you're using the SIFT UI. Same on Android, you could basically be using XML layouts now, but now you have Compost that's coming in. Now these technologies would change all the time, but the core idea of multi-platform here is that the business logic is getting shared across. Mind that I'm not saying this is cross-platform. It comes back to the same thing. When we say cross-platform solutions, we have basically solutions that are, they're asking you to write code in an opinionated manner, right? Also, they are doing some sort of like bridging to make things work for you magically, right? When you say it's a Xamarin app, I write code in C sharp and I write something up and say, for example, like an application in that. And then I deploy it to say Android, iOS and say some other platform maybe desktop. In this case, what they're doing is they are going to compile your code, put it behind a bridging layer and then talk to the native site. So there's still some sort of a dependency in between. If this dependency is not updated, you're already behind. So what's the secret source here? So from my understanding, and this is what I am going to maybe represent it. And maybe you can think through with me as I explained this is that there's a concept called expect an actual concept. What I like to call as interfaces with superpowers and more, and I'm going to explain what that that turns out to be. So this is a standard interface in Kotlin, right? You have an interface that a function called platform name. Then I'm using Android code right now. You have a main activity where I'm kind of, I'm not extending the activity here for some reason, but I should have anyways consider it's a standard class that is implementing the interface and it overrides the function here platform name because I'm using the interface. And then later on I use it inside the function called create application screen message. I'm calling it hello from dollar and then the passing the function in there. Now notice here's something the first section where the interface is declared or I should say defined actually or declared. Yeah. That is the point where we are expecting this to be implemented. This is how we read it, right? And then eventually when we override it is the actual implementation. That's how interfaces work. Now I'm going to map this back to how Kotlin, uh, multi platform is going to be using this kind of a functionality. So what you have is that on your say, you have multiple modules right now in a Kotlin platform project. The common module here would basically say expect. That's the keyword to use. And then it will put it something similar to like how you use core routines. You put suspend and then the function name, right? You're going to say expect the function name and then that's it. Then maybe you can use the same function call in the common code for create application screen message and then eventually in the platform specific code version, you will go and say the actual implementation for this by using the keyword actual is this function and what, what is the implementation you want to define? So in this case, we are defining the string as Android for Android platform module, uh, and iOS for, uh, module. But this not it. And I said, and more with the superpower version is because it's not just limited to how it will work with functions. You can use the same kind of a, of a process when you're doing it with the class, right? So for example, you have a class here greeting, uh, where you say, I'm going to expect this class, uh, to have a function called greet in it. Now the platform implementation for this will map into saying actual the class greeting. And then notice I say actual constructor Val name string. Why am I saying actual again? Because on the platform side, this could have been say swift and it would have said, let name string. So this is also changing for me. So that's why I have to say the actual implementation for the constructor is going to be something that's very specific to Android in this case using content. So Val name string and then eventually I provide the actual implementation of the function here called greet where I say print LN, hello name. And then you can obviously use it based on which platform you're using. In this case, we are considering adroin. So we'll create the class. We'll call the function on it, which will print hello, foster. So that said, let's jump into trying to or or I'm going to, I'm going to go through the steps that you require to start building Kotlin multipliers from code. Uh, now that we know the idea of expect an actual, but before we do that, I want to mention something about sharing is getting. So if you go on the internet right now and you try out like Google searching this, how do you get a Kotlin multipliers from project to work? You'll find many ways. One of the ways of doing this, this code sharing is that you put all your code in just one repository, right? And then everyone just tries to work with that in that same repository. That's okay to work with, but if you have many teams working across different time zones, people are going to be committing code. It's going to conflict and cause a lot of problems. So that's not a good one. The second one is that, uh, you put everything in its own repository in its own project while the shared code that is going to be shared across multiple projects is going to live its own project. It's a bit hard to maintain because you have to keep in sync with the shared code and the other platforms that you are sharing this against. So you have to keep them in sync. Uh, this is what it kind of looks like. So imagine this being a project in Intel J, uh, where I am basically creating a sample app called KMP here. Uh, it has app as a module that is the Android app. It has native slash Kotlin iOS slash Kotlin iOS as the iOS app module here. And then you have a shared code as a full folder here inside which lives something called Android main, which is your Kotlin JVM code, uh, something that lives as common, which is your shared code. And then you have your iOS main, which is your Kotlin native iOS shared code here. Uh, this is basically living outside in a shared code folder. So this is something that you would do, but it's really hard to maintain it at the same time because yes, people would be doing a lot of things at the same time. The third version of doing this is that you have one platform in sync with the common code while the other one lives on the other side, right? So it's it's better. Uh, it's easier to test with. It is better to change things. And this is what it looks like. You have something like this. You have Android app and the Kotlin JVM version living side by side. And then you have your shared code, uh, the Kotlin native iOS code and the iOS app as a different module, right? The shared code and Kotlin native iOS code actually lives inside the app module. As you can see, it's called common main and iOS main. Uh, this is just living inside the app module itself. So we're going to actually start doing this like from scratch, like how you would do this. Um, you would think the thing that it's very easy to work with, but sadly there's no specific ID like Android studio. Uh, but you use kind of like all three IDs here. We'll use Intel J idea. Uh, we'll use a studio and we'll use export. Um, all three of them together to get to get this project working and functional. So you start with Intel J idea. This is the latest one I took the screenshot last night. Uh, you create a new project. You say, I'm going to put a mobile multi platform project with Android and iOS coordinate using greater build tool, uh, define it a name, give it something and then say finish. At this point, when you've hit finish, your project would sing and you would ideally assume that it is functional. Uh, turns out it's not because by default Intel J idea does not put the SDK path for your Android in the local dot properties file. So that is a bit weird because they do that for Android studio or maybe Android studio team does that specifically. Uh, I'm not quite sure. Uh, but in that sense, you will have to actually provide the path here. So I changed this path to something called users slash username. And then I provide the Android SDK path here. When you do this, your project is fully functional at this point. What you do is that you need to also go into your project structure and set the default, uh, like the SDK for all the modules. This is also something that I don't know why it doesn't work, but ideally they should be supported from the ID itself. They know there's other SDK, but they don't choose the default one is 1.8 Java version. So I want to also highlight here. Uh, when you do this, the bizarre version, you actually see something like a common code, the Kotlin native IS code, the Android, uh, and the cotton JVM code. And then there's the is specific code, which is all split into different modules right now. The function calls as you will define, you will mention them as expect in the common code only in the cotton native IS code. You will provide the actual implementation in the Android and Kotlin JVM code. You will provide the actual implementation. The magic behind how all of this is tying together is actually using this, this plugin that you have. You just need to, it is defined in your apps build or gradify. Uh, once you define it, you all have functionalities open like these. You can define the platforms you can target to, uh, under the section Kotlin, uh, you can say IS X 64, which right now is targeting the IS, um, emulator. I could just go ahead and do TV OS X 64 and that would do the same thing. But for the TV OS operating system for the emulator version. And then you define the source that basically defining your dependencies, which you can totally do as you would do in a standard got a graded project. Then because you now want to run your application, you set up the project. Now you need to open up Android studio and select the app module, the one that has your common code to, you will select that run this through. You, as you can see, there are different modules that's synchronizing and then it will be able to execute the application surprisingly. That's nice because now we are going to try doing the same with iOS. So if the iOS again, you go and then you select the folder that is called iOS app. This is outside your app module in your root project. And this is the one you need to select. When you do that, you would assume everything would work, but it does not again. Uh, turns out that's because they, they use a relative path to reference something that doesn't exist. Um, which is also weird. They should not do this. Uh, it should come part of the wizard, but it's not. So you have this error. This error literally says that you have something that's missing and that's a graded new file, right? That's not there. So I need to put a graded wrapper in the root project and I'm going to do that by calling graded wrapper and it will create that for me. That basically allows me to go back into Xcode, hit run and be able to run the app at the same time. So now you have an app running on Android and iOS both. Um, basically the whole project is functional. You can go ahead and write code using Android studio if you want or Intel J idea. Uh, you can just open up the Kotlin file, provide the actual implementation or the more expected functions you would want. So examples in the wild, I want to show this because there's a lot of questions going on. Do people use this in production or not? Like, is this something that we should not be tinkering with? Turns out a lot of companies are doing that. You can see a list of them all working with the links, uh, these all links to their blog post actually, when you download these slides, you can use them and read what they have been working on. Um, JetBrains has recently released spaces, uh, their whole, this system here, which allows to communicate with multiple teams. So that is also working partly native, uh, Scotland, multi-platform. And obviously touch lab is doing a lot of things in this area. So you should totally follow them. Um, they are Kotlin multi-platform libraries. By the way, you can get a list of these, but here's the caveat here is that the ecosystem is still evolving. Uh, the bigger problem is that not many libraries are available at your disposal. And a lot of people, those who are jumping into building these libraries are actually not targeting all the platforms. For example, you wanted to use a multi-platform library right now that targets say, are kind of like does, um, database saving and retrieval of data, right? Um, but it does not target TVOS, but you wanted that functionality and we targeted to TVOS. Well, if the library doesn't support it, it's useless for you, right? You can target for platforms, but not TVOS in general. So that's why not all libraries are actually targeting all the platform. So that's a bit of a problem. Um, that's most of the stuff. There's a resource here. This is like a, um, like, um, I would say a tutorial. Uh, the first thing is more of tutorial on the official Kotlin line site. Uh, the second one is the example that I showed you. Uh, what I do want to also show you is the thing that I was talking about. Um, this is how all the files look like and the implementation. This is the same project as I was talking about. Um, there is a section where I actually call this function, create application screen message, which was running there and I provide the actual functionality here. But some people might even say like, what if I wanted to use Swift UI? That is also possible provided use it in a different way. In this case, you will see, I'm including the shared code functionality, the one that I was explaining way earlier than this. Um, and then I go ahead and I actually call the function here with the common KT file. So you can also use with Swift UI. If you want, if you have compose, you can also use this word. Uh, it should function without any problems. Uh, I will put more examples in this repository so you can also obviously follow this along. Um, and that's it. I guess. Thank you.
 Yeah, everyone again, thank you for coming. Don't forget to yeah, help your chair when  you leave the room. It's really nice. Don't pass in front of the camera over there. And  we still have Japanese licenses. So open for request. Then I'm happy to introduce Nishon.  He is going to talk about Kotlin MP into the multiverse. So please give him a big round  of applause. Okay, hello everyone. You can all hear me right at the back also. I hope  okay great. Thank you all for coming to this talk. So the idea about this talk basically  came through because I was trying to like find out ways of working with Kotlin multi-platform  as like people been talking about it and a lot of things are going around this. So I  eventually started like trying out how I can get this to work. Turns out it's not as easy  as we think it is. So that's how this talk came to be. So what I'm going to be doing  here is I'm going to try to at least convince you all to understand how Kotlin multi-platform  in general is working and what's doing. And then I'm also going to show you how you can  actually get a working application for Android and iOS because it's not as simple as you  think. Like you just fire up an ID and it works. No, it's not that. That's what I will  show you. So let's start with that. So I said Kotlin MP. What does that actually mean? As  you would have guessed, it's basically Kotlin multi-platform. There's no formal definition  for this like what exactly it is. So I came up with my own from what I understood. Basically  we are utilizing Kotlin language to build for these multiple target platforms. I'll get  to what target platforms are in a few minutes, which enables code sharing while being as  flexible as you can be. So I'm going to break this down because like a full statement, okay,  there's a lot of things being said here. In general Kotlin multi-platform is like an open  source tool or I should say plugin. That's available. It uses Kotlin as your common code  here. Also it's targeting multiple platforms. The code sharing is specifically happening  for data domain and presentation layer. The different thing about it is that it integrates  with the existing native platforms. So it leverages the native capabilities of the platform  when it is required. It's not that you are specifically forced to use them. It's more  a choice on you when you need to use them. You will go ahead and use them. It's optional  as it's not opinionated. It ties into the same point as above. It will not ask you to  specifically use a certain pattern. It will not ask you to do some sort of like trickery  or like use a different language to work with. So it's basically trying to help you as much  as it can while giving you all the choices. But the question here is why? Why are we even  trying to do this? So from what I understand is that up till now there have been like all  these different possibilities that we could use Kotlin for. You could use Kotlin for generating  JavaScript code and then you could use Kotlin for generating the JVM base code, the byte  code, right? And then Kotlin native came into place and that allowed people or at least  the Kotlin tool chain to generate more target platform specific code. So you can think of  something that's more near to the machine level code here. And the second point that's  very important is that existing solutions are very opinionated. I'm looking at Flutter,  React Native and then you also have Xamarin. Obviously people have tried CC++ in the past  too. All of these are very opinionated in the sense that they force you to use a certain  pattern. Flutter would basically ask you to use first of all a different language. So  you start from a different stack and a different language. At the same time it tells you that  you cannot use the platform widgets because it is going to be drawing all the widgets  for you on the screen, right? So those kind of like opinionated versions exist and that's  why Kotlin native is Kotlin multi-platform now is something that's more considered.  It's something like this, like we have a situation where it's a dilemma of the mobile app development  right now. If you want to develop a native app for each device and maintain several projects,  this is what it looks like on the right. And then you use a unique framework like say Phone  Gap and then App Accelerator like in the past or you could use Flutter or even React Native.  You end up building something that is limited in functionality. Why am I saying that? Because  there have been companies who have tried this in the production. Like for example, you know,  Airbnb tried React Native and then they pushed back to going to native again. Dropbox tried  CC plus us for their cross-platform capabilities in the application but they also went back  to native because there's certain things that you cannot do when you're trying to share  most of the code across platforms. So let's dive into the multi-verse of platforms here  or target platforms. That's the technical word for it. The way I understand target platform,  I think this was explained in the last talk a little bit. The point here is that I understand  it as compiled artifacts to be consumed by specific platform. So say for example, when  we are considering Kotlin JVM, the artifact that will be consumed by the platform would  be jar and AR files, right? This can be consumed by Java, by Android, by Spring Boot. If you  have Kotlin JS, it's going to be generating JavaScript code which you can bundle it up  and push it with say JavaScript, React, or Node. And then there comes the Kotlin native  part which enabled more possibilities where you have ability to generate code that is  native to the ARM platform or CPU in general that you can push it with the Android and  DK. You have iOS version. The iOS X64 by the way is the emulator. Similar you have for  TVOS. X64 is again emulator version. WatchOS. X86 is again for emulator. And the other  versions are when you want to run them on the device. And then you have more where you  have the Linux ARM version, the MIPS version for the same, MacOS, X64, MINGW which is basically  for Windows, and then the WSM32 which is for WebAssembly. That's what Kotlin native is allowing  you to target now because it's generating artifacts that can be consumed by code that's  running on this platform. So this brings me to the next part here because it's not just  the target platform, it's also about code sharing. So when we say code sharing, we are  actually talking about more related to the data layer in general, right, where you can  put your networking code that can be shared across multiple platforms. You can put caching.  You can put repositories. You can even put something like a presentation layer which  is common on Android side. You have view models and presenters, controllers. And then there's  the domain layer where you can put use cases, entities, and the interactors. What is also  important here is that we are not talking about the UI at all. Now, why we are not talking  about the UI because Kotlin native in general doesn't even care about UI. Each of these  platforms that exist have their own way of representing UI. iOS has its own version. Android  has its own version. Say, example, Linux has its own version, and they all do their job  pretty well. So what the native is basically saying is that we're going to build an artifact  for you. You plug that into your application, build the UI on your own, and then use this  whole code, right? So this is the artifact that has been generated on all of these different  platforms is what is shared, but the UI is still native. This is more or less on the  side of just making sure that the UI gets updated pretty frequently, right? But your  business logic anyway stays the same. So you want to share your business logic mostly and  not the UI. UI can change whenever you want based on whatever technology you use. Even  say, for example, on iOS, we were developing a lot of like UI with, say, you controllers  and other stuff. Now you're using the SIFT UI. Same on Android, you could basically be  using XML layouts now, but now you have Compost that's coming in. Now these technologies would  change all the time, but the core idea of multi-platform here is that the business logic  is getting shared across. Mind that I'm not saying this is cross-platform. It comes back  to the same thing. When we say cross-platform solutions, we have basically solutions that  are, they're asking you to write code in an opinionated manner, right? Also, they are  doing some sort of like bridging to make things work for you magically, right? When you say  it's a Xamarin app, I write code in C sharp and I write something up and say, for example,  like an application in that. And then I deploy it to say Android, iOS and say some other  platform maybe desktop. In this case, what they're doing is they are going to compile  your code, put it behind a bridging layer and then talk to the native site. So there's  still some sort of a dependency in between. If this dependency is not updated, you're  already behind. So what's the secret source here? So from my understanding, and this is  what I am going to maybe represent it. And maybe you can think through with me as I explained  this is that there's a concept called expect an actual concept. What I like to call as  interfaces with superpowers and more, and I'm going to explain what that that turns  out to be. So this is a standard interface in Kotlin, right? You have an interface that  a function called platform name. Then I'm using Android code right now. You have a main  activity where I'm kind of, I'm not extending the activity here for some reason, but I should  have anyways consider it's a standard class that is implementing the interface and it  overrides the function here platform name because I'm using the interface. And then  later on I use it inside the function called create application screen message. I'm calling  it hello from dollar and then the passing the function in there. Now notice here's something  the first section where the interface is declared or I should say defined actually or declared.  Yeah. That is the point where we are expecting this to be implemented. This is how we read  it, right? And then eventually when we override it is the actual implementation. That's how  interfaces work. Now I'm going to map this back to how Kotlin, uh, multi platform is  going to be using this kind of a functionality. So what you have is that on your say, you  have multiple modules right now in a Kotlin platform project. The common module here would  basically say expect. That's the keyword to use. And then it will put it something similar  to like how you use core routines. You put suspend and then the function name, right?  You're going to say expect the function name and then that's it. Then maybe you can use  the same function call in the common code for create application screen message and  then eventually in the platform specific code version, you will go and say the actual implementation  for this by using the keyword actual is this function and what, what is the implementation  you want to define? So in this case, we are defining the string as Android for Android  platform module, uh, and iOS for, uh, module. But this not it. And I said, and more with  the superpower version is because it's not just limited to how it will work with functions.  You can use the same kind of a, of a process when you're doing it with the class, right?  So for example, you have a class here greeting, uh, where you say, I'm going to expect this  class, uh, to have a function called greet in it. Now the platform implementation for  this will map into saying actual the class greeting. And then notice I say actual constructor  Val name string. Why am I saying actual again? Because on the platform side, this could have  been say swift and it would have said, let name string. So this is also changing for  me. So that's why I have to say the actual implementation for the constructor is going  to be something that's very specific to Android in this case using content. So Val name string  and then eventually I provide the actual implementation of the function here called greet where I  say print LN, hello name. And then you can obviously use it based on which platform you're  using. In this case, we are considering adroin. So we'll create the class. We'll call the  function on it, which will print hello, foster. So that said, let's jump into trying to or  or I'm going to, I'm going to go through the steps that you require to start building  Kotlin multipliers from code. Uh, now that we know the idea of expect an actual, but  before we do that, I want to mention something about sharing is getting. So if you go on  the internet right now and you try out like Google searching this, how do you get a Kotlin  multipliers from project to work? You'll find many ways. One of the ways of doing this,  this code sharing is that you put all your code in just one repository, right? And then  everyone just tries to work with that in that same repository. That's okay to work with,  but if you have many teams working across different time zones, people are going to  be committing code. It's going to conflict and cause a lot of problems. So that's not  a good one. The second one is that, uh, you put everything in its own repository in its  own project while the shared code that is going to be shared across multiple projects  is going to live its own project. It's a bit hard to maintain because you have to keep  in sync with the shared code and the other platforms that you are sharing this against.  So you have to keep them in sync. Uh, this is what it kind of looks like. So imagine  this being a project in Intel J, uh, where I am basically creating a sample app called  KMP here. Uh, it has app as a module that is the Android app. It has native slash Kotlin  iOS slash Kotlin iOS as the iOS app module here. And then you have a shared code as a  full folder here inside which lives something called Android main, which is your Kotlin  JVM code, uh, something that lives as common, which is your shared code. And then you have  your iOS main, which is your Kotlin native iOS shared code here. Uh, this is basically  living outside in a shared code folder. So this is something that you would do, but it's  really hard to maintain it at the same time because yes, people would be doing a lot of  things at the same time. The third version of doing this is that you have one platform  in sync with the common code while the other one lives on the other side, right? So it's  it's better. Uh, it's easier to test with. It is better to change things. And this is  what it looks like. You have something like this. You have Android app and the Kotlin  JVM version living side by side. And then you have your shared code, uh, the Kotlin  native iOS code and the iOS app as a different module, right? The shared code and Kotlin  native iOS code actually lives inside the app module. As you can see, it's called common  main and iOS main. Uh, this is just living inside the app module itself. So we're going  to actually start doing this like from scratch, like how you would do this. Um, you would  think the thing that it's very easy to work with, but sadly there's no specific ID like  Android studio. Uh, but you use kind of like all three IDs here. We'll use Intel J idea.  Uh, we'll use a studio and we'll use export. Um, all three of them together to get to get  this project working and functional. So you start with Intel J idea. This is the latest  one I took the screenshot last night. Uh, you create a new project. You say, I'm going  to put a mobile multi platform project with Android and iOS coordinate using greater build  tool, uh, define it a name, give it something and then say finish. At this point, when you've  hit finish, your project would sing and you would ideally assume that it is functional.  Uh, turns out it's not because by default Intel J idea does not put the SDK path for  your Android in the local dot properties file. So that is a bit weird because they do that  for Android studio or maybe Android studio team does that specifically. Uh, I'm not quite  sure. Uh, but in that sense, you will have to actually provide the path here. So I changed  this path to something called users slash username. And then I provide the Android SDK  path here. When you do this, your project is fully functional at this point. What you  do is that you need to also go into your project structure and set the default, uh, like the  SDK for all the modules. This is also something that I don't know why it doesn't work, but  ideally they should be supported from the ID itself. They know there's other SDK, but  they don't choose the default one is 1.8 Java version. So I want to also highlight here.  Uh, when you do this, the bizarre version, you actually see something like a common code,  the Kotlin native IS code, the Android, uh, and the cotton JVM code. And then there's  the is specific code, which is all split into different modules right now. The function  calls as you will define, you will mention them as expect in the common code only in  the cotton native IS code. You will provide the actual implementation in the Android and  Kotlin JVM code. You will provide the actual implementation. The magic behind how all of  this is tying together is actually using this, this plugin that you have. You just need  to, it is defined in your apps build or gradify. Uh, once you define it, you all have functionalities  open like these. You can define the platforms you can target to, uh, under the section  Kotlin, uh, you can say IS X 64, which right now is targeting the IS, um, emulator. I  could just go ahead and do TV OS X 64 and that would do the same thing. But for the  TV OS operating system for the emulator version. And then you define the source that basically  defining your dependencies, which you can totally do as you would do in a standard got  a graded project. Then because you now want to run your application, you set up the project.  Now you need to open up Android studio and select the app module, the one that has your  common code to, you will select that run this through. You, as you can see, there are different  modules that's synchronizing and then it will be able to execute the application surprisingly.  That's nice because now we are going to try doing the same with iOS. So if the iOS again,  you go and then you select the folder that is called iOS app. This is outside your app  module in your root project. And this is the one you need to select. When you do that,  you would assume everything would work, but it does not again. Uh, turns out that's because  they, they use a relative path to reference something that doesn't exist. Um, which is  also weird. They should not do this. Uh, it should come part of the wizard, but it's  not. So you have this error. This error literally says that you have something that's missing  and that's a graded new file, right? That's not there. So I need to put a graded wrapper  in the root project and I'm going to do that by calling graded wrapper and it will create  that for me. That basically allows me to go back into Xcode, hit run and be able to run  the app at the same time. So now you have an app running on Android and iOS both. Um,  basically the whole project is functional. You can go ahead and write code using Android  studio if you want or Intel J idea. Uh, you can just open up the Kotlin file, provide  the actual implementation or the more expected functions you would want. So examples in the  wild, I want to show this because there's a lot of questions going on. Do people use  this in production or not? Like, is this something that we should not be tinkering with? Turns  out a lot of companies are doing that. You can see a list of them all working with the  links, uh, these all links to their blog post actually, when you download these slides,  you can use them and read what they have been working on. Um, JetBrains has recently released  spaces, uh, their whole, this system here, which allows to communicate with multiple  teams. So that is also working partly native, uh, Scotland, multi-platform. And obviously  touch lab is doing a lot of things in this area. So you should totally follow them. Um,  they are Kotlin multi-platform libraries. By the way, you can get a list of these, but  here's the caveat here is that the ecosystem is still evolving. Uh, the bigger problem  is that not many libraries are available at your disposal. And a lot of people, those  who are jumping into building these libraries are actually not targeting all the platforms.  For example, you wanted to use a multi-platform library right now that targets say, are kind  of like does, um, database saving and retrieval of data, right? Um, but it does not target  TVOS, but you wanted that functionality and we targeted to TVOS. Well, if the library  doesn't support it, it's useless for you, right? You can target for platforms, but not  TVOS in general. So that's why not all libraries are actually targeting all the platform. So  that's a bit of a problem. Um, that's most of the stuff. There's a resource here. This  is like a, um, like, um, I would say a tutorial. Uh, the first thing is more of tutorial on  the official Kotlin line site. Uh, the second one is the example that I showed you. Uh,  what I do want to also show you is the thing that I was talking about. Um, this is how  all the files look like and the implementation. This is the same project as I was talking  about. Um, there is a section where I actually call this function, create application screen  message, which was running there and I provide the actual functionality here. But some people  might even say like, what if I wanted to use Swift UI? That is also possible provided  use it in a different way. In this case, you will see, I'm including the shared code functionality,  the one that I was explaining way earlier than this. Um, and then I go ahead and I actually  call the function here with the common KT file. So you can also use with Swift UI. If  you want, if you have compose, you can also use this word. Uh, it should function without  any problems. Uh, I will put more examples in this repository so you can also obviously  follow this along. Um, and that's it. I guess. Thank you.
kotlin_mp_into_the_multi_verse_0_143.png kotlin_mp_into_the_multi_verse_144_2435.png kotlin_mp_into_the_multi_verse_2436_2567.png kotlin_mp_into_the_multi_verse_2568_6731.png kotlin_mp_into_the_multi_verse_6732_8183.png kotlin_mp_into_the_multi_verse_8184_10331.png kotlin_mp_into_the_multi_verse_10332_14639.png kotlin_mp_into_the_multi_verse_14640_14915.png kotlin_mp_into_the_multi_verse_14916_16391.png kotlin_mp_into_the_multi_verse_16392_17579.png kotlin_mp_into_the_multi_verse_17580_19271.png kotlin_mp_into_the_multi_verse_19272_23807.png kotlin_mp_into_the_multi_verse_23808_27887.png kotlin_mp_into_the_multi_verse_27888_28187.png kotlin_mp_into_the_multi_verse_28188_28811.png kotlin_mp_into_the_multi_verse_28812_29531.png kotlin_mp_into_the_multi_verse_29532_29783.png kotlin_mp_into_the_multi_verse_29784_30083.png kotlin_mp_into_the_multi_verse_30084_30539.png kotlin_mp_into_the_multi_verse_30540_32087.png kotlin_mp_into_the_multi_verse_32088_33047.png kotlin_mp_into_the_multi_verse_33048_33275.png kotlin_mp_into_the_multi_verse_33276_33455.png kotlin_mp_into_the_multi_verse_33456_33615.png
Yeah, everyone again, thank you for coming. Don't forget to yeah, help your chair when you leave the room. It's really nice. Don't pass in front of the camera over there. And we still have Japanese licenses. So open for request. Then I'm happy to introduce Nishon. He is going to talk about Kotlin MP into the multiverse. So please give him a big round of applause. Okay, hello everyone. You can all hear me right at the back also. I hope okay great. Thank you all for coming to this talk. So the idea about this talk basically came through because I was trying to like find out ways of working with Kotlin multi-platform as like people been talking about it and a lot of things are going around this. So I eventually started like trying out how I can get this to work. Turns out it's not as easy as we think it is. So that's how this talk came to be. So what I'm going to be doing here is I'm going to try to at least convince you all to understand how Kotlin multi-platform in general is working and what's doing. And then I'm also going to show you how you can actually get a working application for Android and iOS because it's not as simple as you think. Like you just fire up an ID and it works. No, it's not that. That's what I will show you. So let's start with that. So I said Kotlin MP. What does that actually mean? As you would have guessed, it's basically Kotlin multi-platform. There's no formal definition for this like what exactly it is. So I came up with my own from what I understood. Basically we are utilizing Kotlin language to build for these multiple target platforms. I'll get to what target platforms are in a few minutes, which enables code sharing while being as flexible as you can be. So I'm going to break this down because like a full statement, okay, there's a lot of things being said here. In general Kotlin multi-platform is like an open source tool or I should say plugin. That's available. It uses Kotlin as your common code here. Also it's targeting multiple platforms. The code sharing is specifically happening for data domain and presentation layer. The different thing about it is that it integrates with the existing native platforms. So it leverages the native capabilities of the platform when it is required. It's not that you are specifically forced to use them. It's more a choice on you when you need to use them. You will go ahead and use them. It's optional as it's not opinionated. It ties into the same point as above. It will not ask you to specifically use a certain pattern. It will not ask you to do some sort of like trickery or like use a different language to work with. So it's basically trying to help you as much as it can while giving you all the choices. But the question here is why? Why are we even trying to do this? So from what I understand is that up till now there have been like all these different possibilities that we could use Kotlin for. You could use Kotlin for generating JavaScript code and then you could use Kotlin for generating the JVM base code, the byte code, right? And then Kotlin native came into place and that allowed people or at least the Kotlin tool chain to generate more target platform specific code. So you can think of something that's more near to the machine level code here. And the second point that's very important is that existing solutions are very opinionated. I'm looking at Flutter, React Native and then you also have Xamarin. Obviously people have tried CC++ in the past too. All of these are very opinionated in the sense that they force you to use a certain pattern. Flutter would basically ask you to use first of all a different language. So you start from a different stack and a different language. At the same time it tells you that you cannot use the platform widgets because it is going to be drawing all the widgets for you on the screen, right? So those kind of like opinionated versions exist and that's why Kotlin native is Kotlin multi-platform now is something that's more considered. It's something like this, like we have a situation where it's a dilemma of the mobile app development right now. If you want to develop a native app for each device and maintain several projects, this is what it looks like on the right. And then you use a unique framework like say Phone Gap and then App Accelerator like in the past or you could use Flutter or even React Native. You end up building something that is limited in functionality. Why am I saying that? Because there have been companies who have tried this in the production. Like for example, you know, Airbnb tried React Native and then they pushed back to going to native again. Dropbox tried CC plus us for their cross-platform capabilities in the application but they also went back to native because there's certain things that you cannot do when you're trying to share most of the code across platforms. So let's dive into the multi-verse of platforms here or target platforms. That's the technical word for it. The way I understand target platform, I think this was explained in the last talk a little bit. The point here is that I understand it as compiled artifacts to be consumed by specific platform. So say for example, when we are considering Kotlin JVM, the artifact that will be consumed by the platform would be jar and AR files, right? This can be consumed by Java, by Android, by Spring Boot. If you have Kotlin JS, it's going to be generating JavaScript code which you can bundle it up and push it with say JavaScript, React, or Node. And then there comes the Kotlin native part which enabled more possibilities where you have ability to generate code that is native to the ARM platform or CPU in general that you can push it with the Android and DK. You have iOS version. The iOS X64 by the way is the emulator. Similar you have for TVOS. X64 is again emulator version. WatchOS. X86 is again for emulator. And the other versions are when you want to run them on the device. And then you have more where you have the Linux ARM version, the MIPS version for the same, MacOS, X64, MINGW which is basically for Windows, and then the WSM32 which is for WebAssembly. That's what Kotlin native is allowing you to target now because it's generating artifacts that can be consumed by code that's running on this platform. So this brings me to the next part here because it's not just the target platform, it's also about code sharing. So when we say code sharing, we are actually talking about more related to the data layer in general, right, where you can put your networking code that can be shared across multiple platforms. You can put caching. You can put repositories. You can even put something like a presentation layer which is common on Android side. You have view models and presenters, controllers. And then there's the domain layer where you can put use cases, entities, and the interactors. What is also important here is that we are not talking about the UI at all. Now, why we are not talking about the UI because Kotlin native in general doesn't even care about UI. Each of these platforms that exist have their own way of representing UI. iOS has its own version. Android has its own version. Say, example, Linux has its own version, and they all do their job pretty well. So what the native is basically saying is that we're going to build an artifact for you. You plug that into your application, build the UI on your own, and then use this whole code, right? So this is the artifact that has been generated on all of these different platforms is what is shared, but the UI is still native. This is more or less on the side of just making sure that the UI gets updated pretty frequently, right? But your business logic anyway stays the same. So you want to share your business logic mostly and not the UI. UI can change whenever you want based on whatever technology you use. Even say, for example, on iOS, we were developing a lot of like UI with, say, you controllers and other stuff. Now you're using the SIFT UI. Same on Android, you could basically be using XML layouts now, but now you have Compost that's coming in. Now these technologies would change all the time, but the core idea of multi-platform here is that the business logic is getting shared across. Mind that I'm not saying this is cross-platform. It comes back to the same thing. When we say cross-platform solutions, we have basically solutions that are, they're asking you to write code in an opinionated manner, right? Also, they are doing some sort of like bridging to make things work for you magically, right? When you say it's a Xamarin app, I write code in C sharp and I write something up and say, for example, like an application in that. And then I deploy it to say Android, iOS and say some other platform maybe desktop. In this case, what they're doing is they are going to compile your code, put it behind a bridging layer and then talk to the native site. So there's still some sort of a dependency in between. If this dependency is not updated, you're already behind. So what's the secret source here? So from my understanding, and this is what I am going to maybe represent it. And maybe you can think through with me as I explained this is that there's a concept called expect an actual concept. What I like to call as interfaces with superpowers and more, and I'm going to explain what that that turns out to be. So this is a standard interface in Kotlin, right? You have an interface that a function called platform name. Then I'm using Android code right now. You have a main activity where I'm kind of, I'm not extending the activity here for some reason, but I should have anyways consider it's a standard class that is implementing the interface and it overrides the function here platform name because I'm using the interface. And then later on I use it inside the function called create application screen message. I'm calling it hello from dollar and then the passing the function in there. Now notice here's something the first section where the interface is declared or I should say defined actually or declared. Yeah. That is the point where we are expecting this to be implemented. This is how we read it, right? And then eventually when we override it is the actual implementation. That's how interfaces work. Now I'm going to map this back to how Kotlin, uh, multi platform is going to be using this kind of a functionality. So what you have is that on your say, you have multiple modules right now in a Kotlin platform project. The common module here would basically say expect. That's the keyword to use. And then it will put it something similar to like how you use core routines. You put suspend and then the function name, right? You're going to say expect the function name and then that's it. Then maybe you can use the same function call in the common code for create application screen message and then eventually in the platform specific code version, you will go and say the actual implementation for this by using the keyword actual is this function and what, what is the implementation you want to define? So in this case, we are defining the string as Android for Android platform module, uh, and iOS for, uh, module. But this not it. And I said, and more with the superpower version is because it's not just limited to how it will work with functions. You can use the same kind of a, of a process when you're doing it with the class, right? So for example, you have a class here greeting, uh, where you say, I'm going to expect this class, uh, to have a function called greet in it. Now the platform implementation for this will map into saying actual the class greeting. And then notice I say actual constructor Val name string. Why am I saying actual again? Because on the platform side, this could have been say swift and it would have said, let name string. So this is also changing for me. So that's why I have to say the actual implementation for the constructor is going to be something that's very specific to Android in this case using content. So Val name string and then eventually I provide the actual implementation of the function here called greet where I say print LN, hello name. And then you can obviously use it based on which platform you're using. In this case, we are considering adroin. So we'll create the class. We'll call the function on it, which will print hello, foster. So that said, let's jump into trying to or or I'm going to, I'm going to go through the steps that you require to start building Kotlin multipliers from code. Uh, now that we know the idea of expect an actual, but before we do that, I want to mention something about sharing is getting. So if you go on the internet right now and you try out like Google searching this, how do you get a Kotlin multipliers from project to work? You'll find many ways. One of the ways of doing this, this code sharing is that you put all your code in just one repository, right? And then everyone just tries to work with that in that same repository. That's okay to work with, but if you have many teams working across different time zones, people are going to be committing code. It's going to conflict and cause a lot of problems. So that's not a good one. The second one is that, uh, you put everything in its own repository in its own project while the shared code that is going to be shared across multiple projects is going to live its own project. It's a bit hard to maintain because you have to keep in sync with the shared code and the other platforms that you are sharing this against. So you have to keep them in sync. Uh, this is what it kind of looks like. So imagine this being a project in Intel J, uh, where I am basically creating a sample app called KMP here. Uh, it has app as a module that is the Android app. It has native slash Kotlin iOS slash Kotlin iOS as the iOS app module here. And then you have a shared code as a full folder here inside which lives something called Android main, which is your Kotlin JVM code, uh, something that lives as common, which is your shared code. And then you have your iOS main, which is your Kotlin native iOS shared code here. Uh, this is basically living outside in a shared code folder. So this is something that you would do, but it's really hard to maintain it at the same time because yes, people would be doing a lot of things at the same time. The third version of doing this is that you have one platform in sync with the common code while the other one lives on the other side, right? So it's it's better. Uh, it's easier to test with. It is better to change things. And this is what it looks like. You have something like this. You have Android app and the Kotlin JVM version living side by side. And then you have your shared code, uh, the Kotlin native iOS code and the iOS app as a different module, right? The shared code and Kotlin native iOS code actually lives inside the app module. As you can see, it's called common main and iOS main. Uh, this is just living inside the app module itself. So we're going to actually start doing this like from scratch, like how you would do this. Um, you would think the thing that it's very easy to work with, but sadly there's no specific ID like Android studio. Uh, but you use kind of like all three IDs here. We'll use Intel J idea. Uh, we'll use a studio and we'll use export. Um, all three of them together to get to get this project working and functional. So you start with Intel J idea. This is the latest one I took the screenshot last night. Uh, you create a new project. You say, I'm going to put a mobile multi platform project with Android and iOS coordinate using greater build tool, uh, define it a name, give it something and then say finish. At this point, when you've hit finish, your project would sing and you would ideally assume that it is functional. Uh, turns out it's not because by default Intel J idea does not put the SDK path for your Android in the local dot properties file. So that is a bit weird because they do that for Android studio or maybe Android studio team does that specifically. Uh, I'm not quite sure. Uh, but in that sense, you will have to actually provide the path here. So I changed this path to something called users slash username. And then I provide the Android SDK path here. When you do this, your project is fully functional at this point. What you do is that you need to also go into your project structure and set the default, uh, like the SDK for all the modules. This is also something that I don't know why it doesn't work, but ideally they should be supported from the ID itself. They know there's other SDK, but they don't choose the default one is 1.8 Java version. So I want to also highlight here. Uh, when you do this, the bizarre version, you actually see something like a common code, the Kotlin native IS code, the Android, uh, and the cotton JVM code. And then there's the is specific code, which is all split into different modules right now. The function calls as you will define, you will mention them as expect in the common code only in the cotton native IS code. You will provide the actual implementation in the Android and Kotlin JVM code. You will provide the actual implementation. The magic behind how all of this is tying together is actually using this, this plugin that you have. You just need to, it is defined in your apps build or gradify. Uh, once you define it, you all have functionalities open like these. You can define the platforms you can target to, uh, under the section Kotlin, uh, you can say IS X 64, which right now is targeting the IS, um, emulator. I could just go ahead and do TV OS X 64 and that would do the same thing. But for the TV OS operating system for the emulator version. And then you define the source that basically defining your dependencies, which you can totally do as you would do in a standard got a graded project. Then because you now want to run your application, you set up the project. Now you need to open up Android studio and select the app module, the one that has your common code to, you will select that run this through. You, as you can see, there are different modules that's synchronizing and then it will be able to execute the application surprisingly. That's nice because now we are going to try doing the same with iOS. So if the iOS again, you go and then you select the folder that is called iOS app. This is outside your app module in your root project. And this is the one you need to select. When you do that, you would assume everything would work, but it does not again. Uh, turns out that's because they, they use a relative path to reference something that doesn't exist. Um, which is also weird. They should not do this. Uh, it should come part of the wizard, but it's not. So you have this error. This error literally says that you have something that's missing and that's a graded new file, right? That's not there. So I need to put a graded wrapper in the root project and I'm going to do that by calling graded wrapper and it will create that for me. That basically allows me to go back into Xcode, hit run and be able to run the app at the same time. So now you have an app running on Android and iOS both. Um, basically the whole project is functional. You can go ahead and write code using Android studio if you want or Intel J idea. Uh, you can just open up the Kotlin file, provide the actual implementation or the more expected functions you would want. So examples in the wild, I want to show this because there's a lot of questions going on. Do people use this in production or not? Like, is this something that we should not be tinkering with? Turns out a lot of companies are doing that. You can see a list of them all working with the links, uh, these all links to their blog post actually, when you download these slides, you can use them and read what they have been working on. Um, JetBrains has recently released spaces, uh, their whole, this system here, which allows to communicate with multiple teams. So that is also working partly native, uh, Scotland, multi-platform. And obviously touch lab is doing a lot of things in this area. So you should totally follow them. Um, they are Kotlin multi-platform libraries. By the way, you can get a list of these, but here's the caveat here is that the ecosystem is still evolving. Uh, the bigger problem is that not many libraries are available at your disposal. And a lot of people, those who are jumping into building these libraries are actually not targeting all the platforms. For example, you wanted to use a multi-platform library right now that targets say, are kind of like does, um, database saving and retrieval of data, right? Um, but it does not target TVOS, but you wanted that functionality and we targeted to TVOS. Well, if the library doesn't support it, it's useless for you, right? You can target for platforms, but not TVOS in general. So that's why not all libraries are actually targeting all the platform. So that's a bit of a problem. Um, that's most of the stuff. There's a resource here. This is like a, um, like, um, I would say a tutorial. Uh, the first thing is more of tutorial on the official Kotlin line site. Uh, the second one is the example that I showed you. Uh, what I do want to also show you is the thing that I was talking about. Um, this is how all the files look like and the implementation. This is the same project as I was talking about. Um, there is a section where I actually call this function, create application screen message, which was running there and I provide the actual functionality here. But some people might even say like, what if I wanted to use Swift UI? That is also possible provided use it in a different way. In this case, you will see, I'm including the shared code functionality, the one that I was explaining way earlier than this. Um, and then I go ahead and I actually call the function here with the common KT file. So you can also use with Swift UI. If you want, if you have compose, you can also use this word. Uh, it should function without any problems. Uh, I will put more examples in this repository so you can also obviously follow this along. Um, and that's it. I guess. Thank you.
we think it is. So that's how this talk came to language to build for these multiple target platforms. The code sharing is specifically So you start from a different stack and a be shared across multiple platforms. You can put is they are going to compile your code, put it eventually in the platform specific code version, and what, what is the implementation you want to you're using. In this case, we are considering main, which is your Kotlin native iOS shared code you will select that run this through. You, as So now you have an app running on Android and iOS