Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

Interface Builder Is Dead Long Live SwiftUI

But nothing happened! Why? Did I have done something wrong? Let’s debug it. So the code is valid, the debugger is telling me that I increment the variable.

Basically, I have to notify the view that the framework needs to call the body again. Does this mean that the framework will rebuild the UI every time I click the button? Probably not, one thing it’s the definition of your UI, and another is how the UIKit interprets and optimize your definition to render the changes.

How to update a Declarative UI?

@State is a wrapper around an Int that every time the value changes it notify the Host(the UIKit interpreter), and the framework will call body again to see if something changes it will interpret the new description and will draw the changes. That’s a bit different from what we are used to, instead of having instances of the elements and changing the value, we provide a description and tell the framework when it changed. That includes notifying when you want to toggle a button, change the content of a Textfield, or present an ActionSheet instead by calling a function and changing the state of UI elements in UIKit.

With this in mind, let’s see what the other benefits are. There is a live preview initialized by code if you are in macOS Catalina, the good thing is that you can simulate the various state of your App by passing the parameters that you want. So you can preview directly in XCode the multiple states of your App. No need anymore to fake navigation or go through your App, and you can set the views in any state in the preview. Now it’s not perfect, it needs to build the App, and in the Beta, it takes time to render or reload the UI, but still less than rebuilding the App and going through the different flows.

I recommend you to check out “Building Custom Views with SwiftUI” from WWDC2019 at least up to minute 23. It will help you understand how the layout is rendered and what sizes as each view and which position it will have. You will also use “.layoutPriority()” that seems more intuitive than the nightmare that content hugging and content compression resistance priorities are in UIKit.

What are the bad parts of SwiftUI?

View class is clutter with hundreds of methods and modifiers, that gives flexibility on building the framework but really a downside for discoverability. Even with compatibility with UIKit, that means you can use SwiftUI inside UIKit ViewControllers or the other way around, UIViews inside SwiftUI Components. This SDK will only be distributed starting with iOS 13, and it’s not backward compatible, so that means, you need to target update or new release of your App, past September 2020 to cover most of the ios 13 users as recommended by Apple. Today, you can’t do everything in SwiftUI, it’s not really important, it’s good enough, the bases are here to stay, and it will give Apple time to mature the API and the tools. Maybe it will never replace UIKit, and we will have to learn how to live with both.

To sum up, I feel that SwiftUI will allow iOS dev to produce better UI by being straightforward to “test” and verify the implementation. Is it ready yet for developers to start to learn? No, the API it’s still changing, and it’s a good thing, that’s what Beta is for. When will it be ready for prime time? If Apple keep is consistency, around XCode 11.2 or 11.3.

In the meanwhile you can check our example App, EndZone in github.

Continue ReadingInterface Builder Is Dead Long Live SwiftUI

First steps into Kotlin Multiplatform

Introduction

First steps into Kotlin Multiplatform

As you may already know we are big supporters of the Kotlin programming language. From the very moment Google announced it was going to officially supported, we decided to spend some time learning and mastering it. We fell in love with it from the very beginning, from the expressiveness of its type system to the support for higher-order functions, it was great to rediscover Android development with such a powerful tool.

We like to think that was only the beginning and we’ve been watching closely the most recent updates coming from the JetBrains team. One of the most exciting news was the Kotlin team pushing forward to get Kotlin multiplatform working. That meant that besides being able to run Kotlin in Android apps, we can now write iOS apps, backend and frontend web with our favorite language!

First steps into Kotlin Multiplatform

We decided to further investigate and create an app for the two leading platforms, iOS, and Android, using Kotlin multiplatform. It’s still an ongoing effort, and there are many things we want to try and implement, but in the meantime, we want to tell you the things we found in the way.

Model

Kotlin multiplatform projects are usually divided into several modules. There will be one for every single target where we want to build our software, in our case, one for iOS and one for Android. We create another module to reuse code in both platforms, the shared or common module. The way multiplatform build works is by creating an artifact of the shared module -for every target- to later consume it from the different targets.

First steps into Kotlin Multiplatform

That means that Kotlin will generate both, a jar file and a framework file, from the same code for the final projects to consume it. The dashed section of the graphic above shows what we want to achieve. Even though Kotlin multiplatform is meant to be used also in Backend and Web, we will keep those out of the scope of our little experiment.

To configure a multiplatform project and all its dependencies we need first to create a new Gradle module to create the shared module.

shared/build.gradle

kotlin {
    targets {
        fromPreset(presets.jvm, "jvm")

        fromPreset(presets.iosX64, "ios_x86_64")
        fromPreset(presets.iosArm64, "ios_arm64")
        configure([ios_x86_64, ios_arm64]) {
            compilations.main.outputKinds("FRAMEWORK")
        }
    }
    
    sourceSets {
        commonMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib"
            }
        }
        jvmMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
            }
        }
        iosMain {
            dependencies {
            }
        }
        configure([ios_x86_64Main, ios_arm64Main]) {
            dependsOn iosMain
        }
    }
}

configurations {
    compileClasspath
}

We can see a lot of iOS configuration we will later review. Then we can define the Android project configuration and tell Gradle to add a dependency to the shared module.

androidApp/build.gradle.kts

android {
    buildToolsVersion = "28.0.3"
    compileSdkVersion(28)
    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(28)
        multiDexEnabled = true
        versionCode = 1
        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }
    }

    sourceSets {
        getByName("main").java.srcDirs("src/main/kotlin")
    }
}

dependencies {
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support:appcompat-v7:28.0.0")
    implementation("com.android.support:recyclerview-v7:28.0.0")
    implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
    implementation(project(":shared"))
}

Finally, we must configure the iOS project. This is the hardest step in the process because iOS works with its own build toolset. The trick here is to create a new Gradle task to generate a framework artifact. One important thing to keep in mind is that we need to create the artifact for different architectures, x86_64 for the simulator, and arm64 for real devices.

shared/build.gradle

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")

    final String configuration = project.findProperty("CONFIGURATION")?.toUpperCase() ?: "DEBUG"
    final String arch = project.findProperty("ARCHS") ?: "x86_64"

    dependsOn kotlin.targets."ios_${arch}".compilations.main.linkTaskName("FRAMEWORK", configuration)

    from { kotlin.targets."ios_${arch}".compilations.main.getBinary("FRAMEWORK", configuration).parentFile }
    into frameworkDir
}

tasks.build.dependsOn packForXCode

We can now configure an XCode build phase to compile the shared module calling the new Gradle task and include the generated framework into the project.

cd ${SRCROOT}/..
./gradlew :shared:packForXCode 
  -PCONFIGURATION=${CONFIGURATION} 
  -PARCHS=${ARCHS}

Running the most basic checks

Once the project was up and running for both platforms, we wanted to invest in quality. We started configuring SwiftLint in the iOS project by adding a Podfile with the dependency:


platform :ios, "11.4"

target "Multiplatform app" do
  use_frameworks!
  pod "SwiftLint"
end

For Android, we went for our usual tools, ktlint, and detekt. Adding them is easy as the Android project is already built with the very same tools we use in our day to day for these projects.

shared/build.gradle


apply plugin: "io.gitlab.arturbosch.detekt"
apply plugin: "org.jlleitschuh.gradle.ktlint"

ktlint {
    version = "0.30.0"
    verbose = true
    android = false
    outputToConsole = true
    reporters = [ReporterType.PLAIN, ReporterType.CHECKSTYLE]
    filter {
        exclude("**/generated/**")
        include("**/kotlin/**")
    }
}

detekt {
    toolVersion = "1.0.0-RC14"
    input = files("src/main/kotlin")
    filters = ".*/resources/.*,.*/build/.*"
}

check.dependsOn ktlintCheck
check.dependsOn "detekt"

CI

The most important thing after setting some automatic checks in our project is to run them from time to time. We use Bitrise, and from the very beginning, we opted for using two different projects, one for each platform. In this way, we can configure the stack for each independently and run tests for both in parallel!
For Android, we are running all unit tests and lint checks. For iOS, we tried our best to do the same, but we are still finding some problems trying to find a stack supporting modern versions of Gradle and XCode.

Farewell

We are still working hard on solving some of the issues we are finding, like fixing our CI for iOS builds or making the most of our architecture to reuse as much code as possible. We promise this won’t be our last post so subscribe now to our newsletter and don’t miss anything.

Continue ReadingFirst steps into Kotlin Multiplatform

First steps into Kotlin Multiplatform

Introduction

First steps into Kotlin Multiplatform

As you may already know we are big supporters of the Kotlin programming language. From the very moment Google announced it was going to officially supported, we decided to spend some time learning and mastering it. We fell in love with it from the very beginning, from the expressiveness of its type system to the support for higher-order functions, it was great to rediscover Android development with such a powerful tool.

We like to think that was only the beginning and we’ve been watching closely the most recent updates coming from the JetBrains team. One of the most exciting news was the Kotlin team pushing forward to get Kotlin multiplatform working. That meant that besides being able to run Kotlin in Android apps, we can now write iOS apps, backend and frontend web with our favorite language!

First steps into Kotlin Multiplatform

We decided to further investigate and create an app for the two leading platforms, iOS, and Android, using Kotlin multiplatform. It’s still an ongoing effort, and there are many things we want to try and implement, but in the meantime, we want to tell you the things we found in the way.

Model

Kotlin multiplatform projects are usually divided into several modules. There will be one for every single target where we want to build our software, in our case, one for iOS and one for Android. We create another module to reuse code in both platforms, the shared or common module. The way multiplatform build works is by creating an artifact of the shared module -for every target- to later consume it from the different targets.

First steps into Kotlin Multiplatform

That means that Kotlin will generate both, a jar file and a framework file, from the same code for the final projects to consume it. The dashed section of the graphic above shows what we want to achieve. Even though Kotlin multiplatform is meant to be used also in Backend and Web, we will keep those out of the scope of our little experiment.

To configure a multiplatform project and all its dependencies we need first to create a new Gradle module to create the shared module.

shared/build.gradle

kotlin {
    targets {
        fromPreset(presets.jvm, "jvm")

        fromPreset(presets.iosX64, "ios_x86_64")
        fromPreset(presets.iosArm64, "ios_arm64")
        configure([ios_x86_64, ios_arm64]) {
            compilations.main.outputKinds("FRAMEWORK")
        }
    }
    
    sourceSets {
        commonMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib"
            }
        }
        jvmMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
            }
        }
        iosMain {
            dependencies {
            }
        }
        configure([ios_x86_64Main, ios_arm64Main]) {
            dependsOn iosMain
        }
    }
}

configurations {
    compileClasspath
}

We can see a lot of iOS configuration we will later review. Then we can define the Android project configuration and tell Gradle to add a dependency to the shared module.

androidApp/build.gradle.kts

android {
    buildToolsVersion = "28.0.3"
    compileSdkVersion(28)
    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(28)
        multiDexEnabled = true
        versionCode = 1
        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }
    }

    sourceSets {
        getByName("main").java.srcDirs("src/main/kotlin")
    }
}

dependencies {
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support:appcompat-v7:28.0.0")
    implementation("com.android.support:recyclerview-v7:28.0.0")
    implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
    implementation(project(":shared"))
}

Finally, we must configure the iOS project. This is the hardest step in the process because iOS works with its own build toolset. The trick here is to create a new Gradle task to generate a framework artifact. One important thing to keep in mind is that we need to create the artifact for different architectures, x86_64 for the simulator, and arm64 for real devices.

shared/build.gradle

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")

    final String configuration = project.findProperty("CONFIGURATION")?.toUpperCase() ?: "DEBUG"
    final String arch = project.findProperty("ARCHS") ?: "x86_64"

    dependsOn kotlin.targets."ios_${arch}".compilations.main.linkTaskName("FRAMEWORK", configuration)

    from { kotlin.targets."ios_${arch}".compilations.main.getBinary("FRAMEWORK", configuration).parentFile }
    into frameworkDir
}

tasks.build.dependsOn packForXCode

We can now configure an XCode build phase to compile the shared module calling the new Gradle task and include the generated framework into the project.

cd ${SRCROOT}/..
./gradlew :shared:packForXCode 
  -PCONFIGURATION=${CONFIGURATION} 
  -PARCHS=${ARCHS}

Running the most basic checks

Once the project was up and running for both platforms, we wanted to invest in quality. We started configuring SwiftLint in the iOS project by adding a Podfile with the dependency:


platform :ios, "11.4"

target "Multiplatform app" do
  use_frameworks!
  pod "SwiftLint"
end

For Android, we went for our usual tools, ktlint, and detekt. Adding them is easy as the Android project is already built with the very same tools we use in our day to day for these projects.

shared/build.gradle


apply plugin: "io.gitlab.arturbosch.detekt"
apply plugin: "org.jlleitschuh.gradle.ktlint"

ktlint {
    version = "0.30.0"
    verbose = true
    android = false
    outputToConsole = true
    reporters = [ReporterType.PLAIN, ReporterType.CHECKSTYLE]
    filter {
        exclude("**/generated/**")
        include("**/kotlin/**")
    }
}

detekt {
    toolVersion = "1.0.0-RC14"
    input = files("src/main/kotlin")
    filters = ".*/resources/.*,.*/build/.*"
}

check.dependsOn ktlintCheck
check.dependsOn "detekt"

CI

The most important thing after setting some automatic checks in our project is to run them from time to time. We use Bitrise, and from the very beginning, we opted for using two different projects, one for each platform. In this way, we can configure the stack for each independently and run tests for both in parallel!
For Android, we are running all unit tests and lint checks. For iOS, we tried our best to do the same, but we are still finding some problems trying to find a stack supporting modern versions of Gradle and XCode.

Farewell

We are still working hard on solving some of the issues we are finding, like fixing our CI for iOS builds or making the most of our architecture to reuse as much code as possible. We promise this won’t be our last post so subscribe now to our newsletter and don’t miss anything.

Continue ReadingFirst steps into Kotlin Multiplatform

First steps into Kotlin Multiplatform

Introduction

First steps into Kotlin Multiplatform

As you may already know we are big supporters of the Kotlin programming language. From the very moment Google announced it was going to officially supported, we decided to spend some time learning and mastering it. We fell in love with it from the very beginning, from the expressiveness of its type system to the support for higher-order functions, it was great to rediscover Android development with such a powerful tool.

We like to think that was only the beginning and we’ve been watching closely the most recent updates coming from the JetBrains team. One of the most exciting news was the Kotlin team pushing forward to get Kotlin multiplatform working. That meant that besides being able to run Kotlin in Android apps, we can now write iOS apps, backend and frontend web with our favorite language!

First steps into Kotlin Multiplatform

We decided to further investigate and create an app for the two leading platforms, iOS, and Android, using Kotlin multiplatform. It’s still an ongoing effort, and there are many things we want to try and implement, but in the meantime, we want to tell you the things we found in the way.

Model

Kotlin multiplatform projects are usually divided into several modules. There will be one for every single target where we want to build our software, in our case, one for iOS and one for Android. We create another module to reuse code in both platforms, the shared or common module. The way multiplatform build works is by creating an artifact of the shared module -for every target- to later consume it from the different targets.

First steps into Kotlin Multiplatform

That means that Kotlin will generate both, a jar file and a framework file, from the same code for the final projects to consume it. The dashed section of the graphic above shows what we want to achieve. Even though Kotlin multiplatform is meant to be used also in Backend and Web, we will keep those out of the scope of our little experiment.

To configure a multiplatform project and all its dependencies we need first to create a new Gradle module to create the shared module.

shared/build.gradle

kotlin {
    targets {
        fromPreset(presets.jvm, "jvm")

        fromPreset(presets.iosX64, "ios_x86_64")
        fromPreset(presets.iosArm64, "ios_arm64")
        configure([ios_x86_64, ios_arm64]) {
            compilations.main.outputKinds("FRAMEWORK")
        }
    }
    
    sourceSets {
        commonMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib"
            }
        }
        jvmMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
            }
        }
        iosMain {
            dependencies {
            }
        }
        configure([ios_x86_64Main, ios_arm64Main]) {
            dependsOn iosMain
        }
    }
}

configurations {
    compileClasspath
}

We can see a lot of iOS configuration we will later review. Then we can define the Android project configuration and tell Gradle to add a dependency to the shared module.

androidApp/build.gradle.kts

android {
    buildToolsVersion = "28.0.3"
    compileSdkVersion(28)
    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(28)
        multiDexEnabled = true
        versionCode = 1
        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }
    }

    sourceSets {
        getByName("main").java.srcDirs("src/main/kotlin")
    }
}

dependencies {
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support.constraint:constraint-layout:1.1.3")
    implementation("com.android.support:appcompat-v7:28.0.0")
    implementation("com.android.support:recyclerview-v7:28.0.0")
    implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
    implementation(project(":shared"))
}

Finally, we must configure the iOS project. This is the hardest step in the process because iOS works with its own build toolset. The trick here is to create a new Gradle task to generate a framework artifact. One important thing to keep in mind is that we need to create the artifact for different architectures, x86_64 for the simulator, and arm64 for real devices.

shared/build.gradle

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")

    final String configuration = project.findProperty("CONFIGURATION")?.toUpperCase() ?: "DEBUG"
    final String arch = project.findProperty("ARCHS") ?: "x86_64"

    dependsOn kotlin.targets."ios_${arch}".compilations.main.linkTaskName("FRAMEWORK", configuration)

    from { kotlin.targets."ios_${arch}".compilations.main.getBinary("FRAMEWORK", configuration).parentFile }
    into frameworkDir
}

tasks.build.dependsOn packForXCode

We can now configure an XCode build phase to compile the shared module calling the new Gradle task and include the generated framework into the project.

cd ${SRCROOT}/..
./gradlew :shared:packForXCode 
  -PCONFIGURATION=${CONFIGURATION} 
  -PARCHS=${ARCHS}

Running the most basic checks

Once the project was up and running for both platforms, we wanted to invest in quality. We started configuring SwiftLint in the iOS project by adding a Podfile with the dependency:


platform :ios, "11.4"

target "Multiplatform app" do
  use_frameworks!
  pod "SwiftLint"
end

For Android, we went for our usual tools, ktlint, and detekt. Adding them is easy as the Android project is already built with the very same tools we use in our day to day for these projects.

shared/build.gradle


apply plugin: "io.gitlab.arturbosch.detekt"
apply plugin: "org.jlleitschuh.gradle.ktlint"

ktlint {
    version = "0.30.0"
    verbose = true
    android = false
    outputToConsole = true
    reporters = [ReporterType.PLAIN, ReporterType.CHECKSTYLE]
    filter {
        exclude("**/generated/**")
        include("**/kotlin/**")
    }
}

detekt {
    toolVersion = "1.0.0-RC14"
    input = files("src/main/kotlin")
    filters = ".*/resources/.*,.*/build/.*"
}

check.dependsOn ktlintCheck
check.dependsOn "detekt"

CI

The most important thing after setting some automatic checks in our project is to run them from time to time. We use Bitrise, and from the very beginning, we opted for using two different projects, one for each platform. In this way, we can configure the stack for each independently and run tests for both in parallel!
For Android, we are running all unit tests and lint checks. For iOS, we tried our best to do the same, but we are still finding some problems trying to find a stack supporting modern versions of Gradle and XCode.

Farewell

We are still working hard on solving some of the issues we are finding, like fixing our CI for iOS builds or making the most of our architecture to reuse as much code as possible. We promise this won’t be our last post so subscribe now to our newsletter and don’t miss anything.

Continue ReadingFirst steps into Kotlin Multiplatform

End of content

No more pages to load