Our Android 2020 development stack

Our Android 2020 development stack

One of the questions we face when talking with Android developers all around the world is related to the tools we use 🤔 The selection of libraries and frameworks used by our Android team is one of the most interesting details in our development pipeline, so we will try to answer this question in this blog post 😃

Our Android 2020 development stack

When listing the libraries we use, we need to focus on various types of tools based on different topics: static analysis utilities, build tools, networking, persistence, permissions, user interface, core components, and testing. We have a bunch of tools we’ve used for years, and we will review them one by one.

Static analysis utilities & build tools:

These tools are really helpful for us. All they help us to go faster in our daily tasks by automating tasks or any other checks we want to do in our codebase 😍

  • Ktlint: Best Kotlin linter in town.
  • Android Lint: The best safeguard for your Android apps.
  • Lin: An awesome tool used to simplify the usage of the Android Linter created by @serchinastico. Really handy when we want to create custom rules!
  • Ribbonizer: Simple but powerful tool to add a ribbon to launcher icons.
  • Play publisher: Needed to automate our release process for internal and public releases.

Networking:

It’s been a while since we started using tools to generate our networking layer based on a Swagger or OpenAPI yaml file, so the libraries we use under the hood are not so relevant. For our latest project, we’ve used this gradle plugin to generate our API client. However, when there is no chance to generate the API client, and there is no way we can create an OpenAPI file, we use these libraries:

  • Retrofit: If you don’t know this library, you are going to love it! It generates a lot of code for you just from an interface 🤩
  • OkHTTP: The best HTTP client you are going to find. Simple, but powerful 🙂
  • Gson: We’ve been using this library for years! There are other alternatives if you want, but we have to admit we always use this one when using automatically generated code 😃
Our Android 2020 development stack

As the code generated is completely coupled to the libraries used by the generator and the models created by this tool, we always wrap it with an adapter to avoid coupling issues.

Persistence:

We all know how handy our loved shared preferences can be… However, when we need a database, we have two choices:

  • Room: Officially maintained by Google, this is one of the best choices when you need a database.
  • SQLDelight: Generates typesafe Kotlin APIs from SQL queries.

For years we used Realm, but nowadays, the tooling for SQLite is excellent now, so we moved to one of the previous alternatives.

Permissions:

After years developing and maintaining a library to simplify the usage of permissions, we keep using Dexter! This library simplifies a lot the usage of the permissions API, letting you get the answer of a permission request in a callback instead of using the famous onActivityResult method.

Our Android 2020 development stack

User interface:

There is a bunch of libraries we use to build our applications user interface, so we are going to drop here just the most relevant ones:

  • Data Binding: The key to success when talking about the usage of MVVM four our presentation layer.
  • Lifecycle Observer: Handy when you want to listen for the events related to the component’s lifecycle without coupling the implementation to any concrete component.
  • Appcompat: Useful when we need to use components in old Android APIs.
  • ConstraintLayout: The best way to create a responsive layout.
  • Glide: Useful when you need to download and show images asynchronously.
  • Renderers: We’ve been using this library for years and is one of the best libraries to work with recycler view.
  • Calligraphy: Nice library if you want to use custom fonts and for some reason you had no idea this was supported since 2017 🙂 (Thanks random reddit user for pointing me this detail out)
  • Material Components: We try to use standard material components when possible, so this library is really helpful because there is a bunch of them already implemented.
  • Snacky: World-class library if you want to show a snackbar.
  • Lottie: Render After Effects animations natively on Android.

Core components and other useful libs:

There are always a bunch of libraries we need deep down in our architecture, and we them use in every project. Let’s talk about these:

  • Kotlin: Of course!!
  • Coroutines: Asynchronous programming with the best syntax in town.
  • Timber: A small and extensible logger.
  • Libphonenumber: When working with phone numbers in international formats, this library is the best option.
  • OneSignal: One of the best push notifications provider. Depending on the projects, we use the native support, but when possible we use OneSignal.
  • Kodein: For the last projects, we’ve used this dependency injector. However, we recommend you to choose your dependency injector based on your needs!
  • ThreeTenABP: Do you have to work with different regions for your dates? Take a look at this JSR-310 backport for Android.
  • Crashlytics: We’ve used this crash reporter for years, and we never regret.
  • Arrow: We tend to use more and more functional programming concepts in our software design, and we have to admit lenses, the core component, and the effects API are in all our Android projects.
  • Leakcanary: The best memory leak detection library.
Our Android 2020 development stack

Testing:

Prepare your speed face! This is going to be intense:

  • JUnit: Classic test runner.
  • Shot: Handy screenshot testing library.
  • Kotlin Snapshot: If you are looking for snapshot testing, this is your kotlin lib!
  • Kotlin Test: Because sometimes we need to use property based testing and this framework provides an awesome support.
  • Mockito: If you write unit tests, you’ll need a mocking library.
  • MockWebServer: Really handy when we want to write tests to ensure our API client is implemented properly.
  • Robolectric: Needed to run our instrumentation tests as fast as possible.
  • Espresso: Needed to be able to interact with the user interface in our UI tests!
  • Barista: Espresso’s best friend.
  • Jacoco: Needed to get a unified code coverage report.
  • Bitrise: The best CI & CD platform we’ve tested for mobile for now. Even when we prefer any platform we can configure using a yaml file like Travis CI. Bitrise’s emulator performance is way better in this platform than any other competitors.

For us, the key to success in our testing strategy is simple. We need to be able to replace any dependency using test doubles when required. To do this, we use the dependency injector from our UI tests, or we do it manually in our unit and integration tests 😃 If you’d like to know more about it, take a look at these blog posts and also remember to take a look at our testing training.

Our Android 2020 development stack

This is it! 👏 Nevertheless, I’m sure you are missing some libraries while ready this post 🤔 and we miss a bunch too! What about all these jetpack libraries we didn’t mention, and Google released months ago? We use them depending on the projects and the people involved in the project:

  • LiveData: When we use room, and we want to connect our UI with the database using an observable implementation, we use this library.
  • Navigation: It all depends on the developer responsible for the project. I don’t personally use it but, I’ll give it a go on my next project!
  • ViewModel: I use a custom implementation linked with the dependency injector and the lifecycle observer library. However, some of use this library.
  • WorkManager: We don’t always have to schedule tasks, but when we need to do something like this, this is the library we use.
  • CameraX: Used only when needed 📸

If you’d like to know more about these Jetpack Libraries remember we have some training about the most relevant components you can request us when needed.

Now we are over Android friends! I hope you enjoyed this 2020 libraries, frameworks, and tools review 😃 If you use a similar stack or you think there is any other library we should use,  please, let us know in the comments section! See you soon 🤘

Photos by the Google Andorid Team, the Arrow Team, the Open API Generator organization and Mindorks.

Continue Reading Our Android 2020 development stack

Our Android 2020 development stack

Our Android 2020 development stack

One of the questions we face when talking with Android developers all around the world is related to the tools we use 🤔 The selection of libraries and frameworks used by our Android team is one of the most interesting details in our development pipeline, so we will try to answer this question in this blog post 😃

Our Android 2020 development stack

When listing the libraries we use, we need to focus on various types of tools based on different topics: static analysis utilities, build tools, networking, persistence, permissions, user interface, core components, and testing. We have a bunch of tools we’ve used for years, and we will review them one by one.

Static analysis utilities & build tools:

These tools are really helpful for us. All they help us to go faster in our daily tasks by automating tasks or any other checks we want to do in our codebase 😍

  • Ktlint: Best Kotlin linter in town.
  • Android Lint: The best safeguard for your Android apps.
  • Lin: An awesome tool used to simplify the usage of the Android Linter created by @serchinastico. Really handy when we want to create custom rules!
  • Ribbonizer: Simple but powerful tool to add a ribbon to launcher icons.
  • Play publisher: Needed to automate our release process for internal and public releases.

Networking:

It’s been a while since we started using tools to generate our networking layer based on a Swagger or OpenAPI yaml file, so the libraries we use under the hood are not so relevant. For our latest project, we’ve used this gradle plugin to generate our API client. However, when there is no chance to generate the API client, and there is no way we can create an OpenAPI file, we use these libraries:

  • Retrofit: If you don’t know this library, you are going to love it! It generates a lot of code for you just from an interface 🤩
  • OkHTTP: The best HTTP client you are going to find. Simple, but powerful 🙂
  • Gson: We’ve been using this library for years! There are other alternatives if you want, but we have to admit we always use this one when using automatically generated code 😃
Our Android 2020 development stack

As the code generated is completely coupled to the libraries used by the generator and the models created by this tool, we always wrap it with an adapter to avoid coupling issues.

Persistence:

We all know how handy our loved shared preferences can be… However, when we need a database, we have two choices:

  • Room: Officially maintained by Google, this is one of the best choices when you need a database.
  • SQLDelight: Generates typesafe Kotlin APIs from SQL queries.

For years we used Realm, but nowadays, the tooling for SQLite is excellent now, so we moved to one of the previous alternatives.

Permissions:

After years developing and maintaining a library to simplify the usage of permissions, we keep using Dexter! This library simplifies a lot the usage of the permissions API, letting you get the answer of a permission request in a callback instead of using the famous onActivityResult method.

Our Android 2020 development stack

User interface:

There is a bunch of libraries we use to build our applications user interface, so we are going to drop here just the most relevant ones:

  • Data Binding: The key to success when talking about the usage of MVVM four our presentation layer.
  • Lifecycle Observer: Handy when you want to listen for the events related to the component’s lifecycle without coupling the implementation to any concrete component.
  • Appcompat: Useful when we need to use components in old Android APIs.
  • ConstraintLayout: The best way to create a responsive layout.
  • Glide: Useful when you need to download and show images asynchronously.
  • Renderers: We’ve been using this library for years and is one of the best libraries to work with recycler view.
  • Calligraphy: Nice library if you want to use custom fonts and for some reason you had no idea this was supported since 2017 🙂 (Thanks random reddit user for pointing me this detail out)
  • Material Components: We try to use standard material components when possible, so this library is really helpful because there is a bunch of them already implemented.
  • Snacky: World-class library if you want to show a snackbar.
  • Lottie: Render After Effects animations natively on Android.

Core components and other useful libs:

There are always a bunch of libraries we need deep down in our architecture, and we them use in every project. Let’s talk about these:

  • Kotlin: Of course!!
  • Coroutines: Asynchronous programming with the best syntax in town.
  • Timber: A small and extensible logger.
  • Libphonenumber: When working with phone numbers in international formats, this library is the best option.
  • OneSignal: One of the best push notifications provider. Depending on the projects, we use the native support, but when possible we use OneSignal.
  • Kodein: For the last projects, we’ve used this dependency injector. However, we recommend you to choose your dependency injector based on your needs!
  • ThreeTenABP: Do you have to work with different regions for your dates? Take a look at this JSR-310 backport for Android.
  • Crashlytics: We’ve used this crash reporter for years, and we never regret.
  • Arrow: We tend to use more and more functional programming concepts in our software design, and we have to admit lenses, the core component, and the effects API are in all our Android projects.
  • Leakcanary: The best memory leak detection library.
Our Android 2020 development stack

Testing:

Prepare your speed face! This is going to be intense:

  • JUnit: Classic test runner.
  • Shot: Handy screenshot testing library.
  • Kotlin Snapshot: If you are looking for snapshot testing, this is your kotlin lib!
  • Kotlin Test: Because sometimes we need to use property based testing and this framework provides an awesome support.
  • Mockito: If you write unit tests, you’ll need a mocking library.
  • MockWebServer: Really handy when we want to write tests to ensure our API client is implemented properly.
  • Robolectric: Needed to run our instrumentation tests as fast as possible.
  • Espresso: Needed to be able to interact with the user interface in our UI tests!
  • Barista: Espresso’s best friend.
  • Jacoco: Needed to get a unified code coverage report.
  • Bitrise: The best CI & CD platform we’ve tested for mobile for now. Even when we prefer any platform we can configure using a yaml file like Travis CI. Bitrise’s emulator performance is way better in this platform than any other competitors.

For us, the key to success in our testing strategy is simple. We need to be able to replace any dependency using test doubles when required. To do this, we use the dependency injector from our UI tests, or we do it manually in our unit and integration tests 😃 If you’d like to know more about it, take a look at these blog posts and also remember to take a look at our testing training.

Our Android 2020 development stack

This is it! 👏 Nevertheless, I’m sure you are missing some libraries while ready this post 🤔 and we miss a bunch too! What about all these jetpack libraries we didn’t mention, and Google released months ago? We use them depending on the projects and the people involved in the project:

  • LiveData: When we use room, and we want to connect our UI with the database using an observable implementation, we use this library.
  • Navigation: It all depends on the developer responsible for the project. I don’t personally use it but, I’ll give it a go on my next project!
  • ViewModel: I use a custom implementation linked with the dependency injector and the lifecycle observer library. However, some of use this library.
  • WorkManager: We don’t always have to schedule tasks, but when we need to do something like this, this is the library we use.
  • CameraX: Used only when needed 📸

If you’d like to know more about these Jetpack Libraries remember we have some training about the most relevant components you can request us when needed.

Now we are over Android friends! I hope you enjoyed this 2020 libraries, frameworks, and tools review 😃 If you use a similar stack or you think there is any other library we should use,  please, let us know in the comments section! See you soon 🤘

Photos by the Google Andorid Team, the Arrow Team, the Open API Generator organization and Mindorks.

Continue Reading Our Android 2020 development stack

Our Android 2020 development stack

Our Android 2020 development stack

One of the questions we face when talking with Android developers all around the world is related to the tools we use 🤔 The selection of libraries and frameworks used by our Android team is one of the most interesting details in our development pipeline, so we will try to answer this question in this blog post 😃

Our Android 2020 development stack

When listing the libraries we use, we need to focus on various types of tools based on different topics: static analysis utilities, build tools, networking, persistence, permissions, user interface, core components, and testing. We have a bunch of tools we’ve used for years, and we will review them one by one.

Static analysis utilities & build tools:

These tools are really helpful for us. All they help us to go faster in our daily tasks by automating tasks or any other checks we want to do in our codebase 😍

  • Ktlint: Best Kotlin linter in town.
  • Android Lint: The best safeguard for your Android apps.
  • Lin: An awesome tool used to simplify the usage of the Android Linter created by @serchinastico. Really handy when we want to create custom rules!
  • Ribbonizer: Simple but powerful tool to add a ribbon to launcher icons.
  • Play publisher: Needed to automate our release process for internal and public releases.

Networking:

It’s been a while since we started using tools to generate our networking layer based on a Swagger or OpenAPI yaml file, so the libraries we use under the hood are not so relevant. For our latest project, we’ve used this gradle plugin to generate our API client. However, when there is no chance to generate the API client, and there is no way we can create an OpenAPI file, we use these libraries:

  • Retrofit: If you don’t know this library, you are going to love it! It generates a lot of code for you just from an interface 🤩
  • OkHTTP: The best HTTP client you are going to find. Simple, but powerful 🙂
  • Gson: We’ve been using this library for years! There are other alternatives if you want, but we have to admit we always use this one when using automatically generated code 😃
Our Android 2020 development stack

As the code generated is completely coupled to the libraries used by the generator and the models created by this tool, we always wrap it with an adapter to avoid coupling issues.

Persistence:

We all know how handy our loved shared preferences can be… However, when we need a database, we have two choices:

  • Room: Officially maintained by Google, this is one of the best choices when you need a database.
  • SQLDelight: Generates typesafe Kotlin APIs from SQL queries.

For years we used Realm, but nowadays, the tooling for SQLite is excellent now, so we moved to one of the previous alternatives.

Permissions:

After years developing and maintaining a library to simplify the usage of permissions, we keep using Dexter! This library simplifies a lot the usage of the permissions API, letting you get the answer of a permission request in a callback instead of using the famous onActivityResult method.

Our Android 2020 development stack

User interface:

There is a bunch of libraries we use to build our applications user interface, so we are going to drop here just the most relevant ones:

  • Data Binding: The key to success when talking about the usage of MVVM four our presentation layer.
  • Lifecycle Observer: Handy when you want to listen for the events related to the component’s lifecycle without coupling the implementation to any concrete component.
  • Appcompat: Useful when we need to use components in old Android APIs.
  • ConstraintLayout: The best way to create a responsive layout.
  • Glide: Useful when you need to download and show images asynchronously.
  • Renderers: We’ve been using this library for years and is one of the best libraries to work with recycler view.
  • Calligraphy: Nice library if you want to use custom fonts and for some reason you had no idea this was supported since 2017 🙂 (Thanks random reddit user for pointing me this detail out)
  • Material Components: We try to use standard material components when possible, so this library is really helpful because there is a bunch of them already implemented.
  • Snacky: World-class library if you want to show a snackbar.
  • Lottie: Render After Effects animations natively on Android.

Core components and other useful libs:

There are always a bunch of libraries we need deep down in our architecture, and we them use in every project. Let’s talk about these:

  • Kotlin: Of course!!
  • Coroutines: Asynchronous programming with the best syntax in town.
  • Timber: A small and extensible logger.
  • Libphonenumber: When working with phone numbers in international formats, this library is the best option.
  • OneSignal: One of the best push notifications provider. Depending on the projects, we use the native support, but when possible we use OneSignal.
  • Kodein: For the last projects, we’ve used this dependency injector. However, we recommend you to choose your dependency injector based on your needs!
  • ThreeTenABP: Do you have to work with different regions for your dates? Take a look at this JSR-310 backport for Android.
  • Crashlytics: We’ve used this crash reporter for years, and we never regret.
  • Arrow: We tend to use more and more functional programming concepts in our software design, and we have to admit lenses, the core component, and the effects API are in all our Android projects.
  • Leakcanary: The best memory leak detection library.
Our Android 2020 development stack

Testing:

Prepare your speed face! This is going to be intense:

  • JUnit: Classic test runner.
  • Shot: Handy screenshot testing library.
  • Kotlin Snapshot: If you are looking for snapshot testing, this is your kotlin lib!
  • Kotlin Test: Because sometimes we need to use property based testing and this framework provides an awesome support.
  • Mockito: If you write unit tests, you’ll need a mocking library.
  • MockWebServer: Really handy when we want to write tests to ensure our API client is implemented properly.
  • Robolectric: Needed to run our instrumentation tests as fast as possible.
  • Espresso: Needed to be able to interact with the user interface in our UI tests!
  • Barista: Espresso’s best friend.
  • Jacoco: Needed to get a unified code coverage report.
  • Bitrise: The best CI & CD platform we’ve tested for mobile for now. Even when we prefer any platform we can configure using a yaml file like Travis CI. Bitrise’s emulator performance is way better in this platform than any other competitors.

For us, the key to success in our testing strategy is simple. We need to be able to replace any dependency using test doubles when required. To do this, we use the dependency injector from our UI tests, or we do it manually in our unit and integration tests 😃 If you’d like to know more about it, take a look at these blog posts and also remember to take a look at our testing training.

Our Android 2020 development stack

This is it! 👏 Nevertheless, I’m sure you are missing some libraries while ready this post 🤔 and we miss a bunch too! What about all these jetpack libraries we didn’t mention, and Google released months ago? We use them depending on the projects and the people involved in the project:

  • LiveData: When we use room, and we want to connect our UI with the database using an observable implementation, we use this library.
  • Navigation: It all depends on the developer responsible for the project. I don’t personally use it but, I’ll give it a go on my next project!
  • ViewModel: I use a custom implementation linked with the dependency injector and the lifecycle observer library. However, some of use this library.
  • WorkManager: We don’t always have to schedule tasks, but when we need to do something like this, this is the library we use.
  • CameraX: Used only when needed 📸

If you’d like to know more about these Jetpack Libraries remember we have some training about the most relevant components you can request us when needed.

Now we are over Android friends! I hope you enjoyed this 2020 libraries, frameworks, and tools review 😃 If you use a similar stack or you think there is any other library we should use,  please, let us know in the comments section! See you soon 🤘

Photos by the Google Andorid Team, the Arrow Team, the Open API Generator organization and Mindorks.

Continue Reading Our Android 2020 development stack

Our Android 2020 development stack

Our Android 2020 development stack

One of the questions we face when talking with Android developers all around the world is related to the tools we use 🤔 The selection of libraries and frameworks used by our Android team is one of the most interesting details in our development pipeline, so we will try to answer this question in this blog post 😃

Our Android 2020 development stack

When listing the libraries we use, we need to focus on various types of tools based on different topics: static analysis utilities, build tools, networking, persistence, permissions, user interface, core components, and testing. We have a bunch of tools we’ve used for years, and we will review them one by one.

Static analysis utilities & build tools:

These tools are really helpful for us. All they help us to go faster in our daily tasks by automating tasks or any other checks we want to do in our codebase 😍

  • Ktlint: Best Kotlin linter in town.
  • Android Lint: The best safeguard for your Android apps.
  • Lin: An awesome tool used to simplify the usage of the Android Linter created by @serchinastico. Really handy when we want to create custom rules!
  • Ribbonizer: Simple but powerful tool to add a ribbon to launcher icons.
  • Play publisher: Needed to automate our release process for internal and public releases.

Networking:

It’s been a while since we started using tools to generate our networking layer based on a Swagger or OpenAPI yaml file, so the libraries we use under the hood are not so relevant. For our latest project, we’ve used this gradle plugin to generate our API client. However, when there is no chance to generate the API client, and there is no way we can create an OpenAPI file, we use these libraries:

  • Retrofit: If you don’t know this library, you are going to love it! It generates a lot of code for you just from an interface 🤩
  • OkHTTP: The best HTTP client you are going to find. Simple, but powerful 🙂
  • Gson: We’ve been using this library for years! There are other alternatives if you want, but we have to admit we always use this one when using automatically generated code 😃
Our Android 2020 development stack

As the code generated is completely coupled to the libraries used by the generator and the models created by this tool, we always wrap it with an adapter to avoid coupling issues.

Persistence:

We all know how handy our loved shared preferences can be… However, when we need a database, we have two choices:

  • Room: Officially maintained by Google, this is one of the best choices when you need a database.
  • SQLDelight: Generates typesafe Kotlin APIs from SQL queries.

For years we used Realm, but nowadays, the tooling for SQLite is excellent now, so we moved to one of the previous alternatives.

Permissions:

After years developing and maintaining a library to simplify the usage of permissions, we keep using Dexter! This library simplifies a lot the usage of the permissions API, letting you get the answer of a permission request in a callback instead of using the famous onActivityResult method.

Our Android 2020 development stack

User interface:

There is a bunch of libraries we use to build our applications user interface, so we are going to drop here just the most relevant ones:

  • Data Binding: The key to success when talking about the usage of MVVM four our presentation layer.
  • Lifecycle Observer: Handy when you want to listen for the events related to the component’s lifecycle without coupling the implementation to any concrete component.
  • Appcompat: Useful when we need to use components in old Android APIs.
  • ConstraintLayout: The best way to create a responsive layout.
  • Glide: Useful when you need to download and show images asynchronously.
  • Renderers: We’ve been using this library for years and is one of the best libraries to work with recycler view.
  • Calligraphy: Nice library if you want to use custom fonts and for some reason you had no idea this was supported since 2017 🙂 (Thanks random reddit user for pointing me this detail out)
  • Material Components: We try to use standard material components when possible, so this library is really helpful because there is a bunch of them already implemented.
  • Snacky: World-class library if you want to show a snackbar.
  • Lottie: Render After Effects animations natively on Android.

Core components and other useful libs:

There are always a bunch of libraries we need deep down in our architecture, and we them use in every project. Let’s talk about these:

  • Kotlin: Of course!!
  • Coroutines: Asynchronous programming with the best syntax in town.
  • Timber: A small and extensible logger.
  • Libphonenumber: When working with phone numbers in international formats, this library is the best option.
  • OneSignal: One of the best push notifications provider. Depending on the projects, we use the native support, but when possible we use OneSignal.
  • Kodein: For the last projects, we’ve used this dependency injector. However, we recommend you to choose your dependency injector based on your needs!
  • ThreeTenABP: Do you have to work with different regions for your dates? Take a look at this JSR-310 backport for Android.
  • Crashlytics: We’ve used this crash reporter for years, and we never regret.
  • Arrow: We tend to use more and more functional programming concepts in our software design, and we have to admit lenses, the core component, and the effects API are in all our Android projects.
  • Leakcanary: The best memory leak detection library.
Our Android 2020 development stack

Testing:

Prepare your speed face! This is going to be intense:

  • JUnit: Classic test runner.
  • Shot: Handy screenshot testing library.
  • Kotlin Snapshot: If you are looking for snapshot testing, this is your kotlin lib!
  • Kotlin Test: Because sometimes we need to use property based testing and this framework provides an awesome support.
  • Mockito: If you write unit tests, you’ll need a mocking library.
  • MockWebServer: Really handy when we want to write tests to ensure our API client is implemented properly.
  • Robolectric: Needed to run our instrumentation tests as fast as possible.
  • Espresso: Needed to be able to interact with the user interface in our UI tests!
  • Barista: Espresso’s best friend.
  • Jacoco: Needed to get a unified code coverage report.
  • Bitrise: The best CI & CD platform we’ve tested for mobile for now. Even when we prefer any platform we can configure using a yaml file like Travis CI. Bitrise’s emulator performance is way better in this platform than any other competitors.

For us, the key to success in our testing strategy is simple. We need to be able to replace any dependency using test doubles when required. To do this, we use the dependency injector from our UI tests, or we do it manually in our unit and integration tests 😃 If you’d like to know more about it, take a look at these blog posts and also remember to take a look at our testing training.

Our Android 2020 development stack

This is it! 👏 Nevertheless, I’m sure you are missing some libraries while ready this post 🤔 and we miss a bunch too! What about all these jetpack libraries we didn’t mention, and Google released months ago? We use them depending on the projects and the people involved in the project:

  • LiveData: When we use room, and we want to connect our UI with the database using an observable implementation, we use this library.
  • Navigation: It all depends on the developer responsible for the project. I don’t personally use it but, I’ll give it a go on my next project!
  • ViewModel: I use a custom implementation linked with the dependency injector and the lifecycle observer library. However, some of use this library.
  • WorkManager: We don’t always have to schedule tasks, but when we need to do something like this, this is the library we use.
  • CameraX: Used only when needed 📸

If you’d like to know more about these Jetpack Libraries remember we have some training about the most relevant components you can request us when needed.

Now we are over Android friends! I hope you enjoyed this 2020 libraries, frameworks, and tools review 😃 If you use a similar stack or you think there is any other library we should use,  please, let us know in the comments section! See you soon 🤘

Photos by the Google Andorid Team, the Arrow Team, the Open API Generator organization and Mindorks.

Continue Reading Our Android 2020 development stack

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Shared Library in Kotlin Multiplatform

Here is the second post from our series about Kotlin Multiplatform focused on mobile app development. Check out the first steps into Kotlin Multiplatform, we always want to share with you our experience in development and we hope this kind of series will help you to build your first Multiplatform application in Kotlin.

The purpose of this post is to show you how to integrate your common module into two different mobile platforms. We will also review the problems and solutions we found while using this development approach. From the UI layer to automated testing, or some troubles we found while coding.

If you want to read more about this Architecture, you can read GUI Architecture by Martin Fowler.

Shared Library goals

Sharing code between platforms by using the same library can be a formidable but we first need to have clear our goals:

  • To share as much code as possible, that is, to avoid re-implementing the same things for every platform we want to support.
  • To have the ability to provide the dependencies once for every platform without needing to build the dependencies twice.
  • We don’t want to solve dependency inversion using different dependency injectors or providers for each platform. Ideally, we want only one dependency injector.
  • To be able to replace dependencies in tests.
  • Write tests as we are used to: UI testing, integration testing, etc…

Implementing the UI layer

Now, when we thought about which architecture should we use for our task, we had it clear: for our first attempt we’d use Model View Presenter.

Shared Library in Kotlin Multiplatform
Image from Jt Liew in his post MVP Kotlin Multiplatform

MVP was created to improve the way UI tests are written. The creators of the pattern needed to write automated tests for the UI layer without any real GUI involved as the subject under test. That’s why they decided to move all the presentation logic to the classes named “presenters”.

Applying this pattern, and moving the UI behavior inside our shared library, will help us a lot to achieve our goal. All the code related to the UI rendering (but the actual drawing part, coupled to the native platforms) will be moved to our shared library. This will help us define a public view contract every platform will have to implement. Therefore, we will simplify every platform implementation because we will have to only think about how the UI will show the already defined behavior.

Platform-specific infrastructure

The first problems you will face will be related to the infrastructure code. You will want to request information from any data source, like network or a local database. Perhaps, you just want to print some logs that you will need to see in both, Android and iOS. For this kind of problems, we need to declare

expected

features we want to implement in every platform. At the same time, platform-specific code will declare its

actual

implementation of those expected features. These keywords are very well explained in the official documentation.

Luckily, we won’t have to write this code twice. Most of the things we will require are already done in libraries that implement the solution in the multiple platforms Kotlin Native support.

Here is a set of libraries that have support for kotlin multiplatform:

Real life

Multiplatform projects are an experimental feature in Kotlin 1.2 and 1.3. All of the language and tooling features described in this document are subject to change in future Kotlin versions.

We want you to know we had problems with 1.3.30 Kotlin versions. These are some of the issues we found while creating a shared library with Kotlin Multiplatform.

  • Native tests worked but it would randomly skip some tests.
  • Our shared library wasn’t refreshed sometimes after updating its code. This made us thought we couldn’t rely on the iOS code we were running.
  • Compile time is a problem. The average compile time now is about 5 minutes.

Another example of the issues we found is related to the Kotlin version upgrade. We found that, once Kotlin 1.3.40 was released, and after updating our project to use it, the app stopped compiling. One of the key problems with this is that if you have many dependencies like we did they may have not updated to the very last version of Kotlin, and therefore, when you do, there might be inconsistencies until they decide to support it. Besides, remember to always upgrade the gradle wrapper.

Dealing with iOS and XCode

You will most probably find a lot of issues when working with iOS. If you find yourself being able to make your Android app but not yours iOS one, here are some tips we got from first-hand experience.

Using static objects or fields will use the

frozen

modifier in iOS. That means they will be immutable. If you have some mutable variable in a static context, then you won’t be able to replace it in runtime, otherwise you’ll get an `InvalidMutabilityException` exception. You can read how mutability works in Kotlin Native in this document, and see an example of how we use it to replace dependency implementations at runtime in the Karumi KotlinMultiplatformApp Github repository.

As we have mentioned before we use the library Ktor client for HTTP requests and they have some old issues that are still present like issue #1165: Ktor client cannot catch offline exceptions and issue #887: InvalidMutabilityException on HttpRequestPipeline when your HttpClient object is on a static context and you try to make a POST/PUT request. You will find nasty crashes while your Android app will work perfectly.

Automated testing

Last but not least, we wanted to know if the current testing stack could be used like we are used to in any other Android or iOS project. Here are some thoughts about the testing strategy for any Mobile Multiplatform app.

As we knew, we can’t really make sure our iOS code works even though it does in Android. That’s why we wanted to do integration testing in every platform and make sure we are not breaking things. For that we had to go as deep as possible on our stack.

We needed a service locator to provide us dependencies, and more importantly, to replace instances in tests. We haven’t found any Multiplatform project meeting these requirements yet. If you know of any, please drop a comment.

The following snippet is an example of how to handle Mutability in our service locator using

AtomicReference

.

InjectionModule

is the place where we save our dependencies to be replaced using Swift and Kotlin. You can see the complete code in our github repository.


object GalleryInjector {
  private val galleryInjector = AtomicReference<InjectionModule?>(null)
  private val defaultInjector = InjectionModule()

  operator fun invoke(): InjectionModule =
    galleryInjector.value ?: defaultInjector

  fun config(injector: InjectionModule) {
    galleryInjector.value = injector.freeze()
  }
}

The problem here is we need to use mockito or mockk and we can’t use it in Swift. That’s why we have to create some stubs manually in Kotlin in order to use them in iOS tests.

Here is how we replace them in Android Tests.


val apiClient = mock<PhotosApiClient> {
      onBlocking { getPhotos() } doThrow NullPointerException()
    }

GalleryInjector.config(PhotoListStub(apiClient))

And here is how we replace them in iOS.


let injectionModule = TestModule(apiClient: PhotoApiClientStub(photos: photos, withErrors: false))
        GalleryInjector().config(injector: injectionModule)

We decided not to write native tests for presenters and that was only because we didn’t know we could create unit tests, translate them to Swift and run them in a native environment. That’d save us a lot of duplicated tests.

Final thoughts

Kotlin Multiplatform is an awesome solution to create a common library for our projects. This approach unlocks an interesting feature, to create rich models and share most of the app behavior between platforms. Based on this solution we can minimize the amount of code we need to create our apps.

There is an interesting detail about the compiler you should keep in mind when you find yourself having problems with iOS builds. You can see the generated Swift code to try to understand what is wrong with your Kotlin native code, or at least, how the generated code works.

Remember, Kotlin Multiplatform is experimental for now and it has a lot of bugs. It is not production ready, but it brings a new world when talking about how to share code between different platforms.

You can see the full source code used on this blog post on Github, you can see how to build the complete stack including integration tests to your project.

We will keep working on the project, talking about databases, network requests, and automated testing… If you want to know more about Kotlin Multiplatform, just drop a comment below with the topics you are more interested in!

Continue Reading Shared Library in Kotlin Multiplatform

End of content

No more pages to load