iOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

One of the biggest complaints you can find between iOS developers is that sometimes, the feedback loop you have when you are doing some fine-tuning of the UI is long. It produces a new Swift compilation, creates a new binary, then the app gets deployed to the simulator, once that’s done, the system will start the app, and then you will be able to navigate to the right screen to check if those small changes are ok.

Sounds familiar?

Meanwhile, you can see your colleges developing websites or React Native apps that they get feedback almost immediately, and they can even modify the UI with a designer in “real-time.”

Feel any envy yet?

What if I tell you that in iOS, we can achieve something similar to that with almost no effort? Would you believe me?

In Karumi, we’ve been playing a bit with a tool that will help us to hot-swap our code so we can shrink our feedback loop duration to just a couple of seconds.

Injection III to the rescue.

This tool created by John Holdsworth will be the one doing all the magic under the hood; it will be checking which files are being changed, compile them, and dynamically insert that code in your running app. Let’s create a tiny example so we can test how this works.

First, we need to install this app from the AppStore and run it.

HotSwapp.

So, let’s create a brand new iOS project, a “Single View App” with Swift and Storyboards, nothing fancy.

Although Injection III has no issues with Storyboards and xibs, I do ( 😬 ), so let’s get rid of the main storyboard and modify our ViewController to contain a label center on the screen.

Now it’s time to setup Injection III to be able to edit our label in real-time.

First, we have to load a bundle into our app that will help us with the method swizzling. In our AppDelegate we will add the following lines:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         ...
    #if DEBUG
        Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
     #endif
        ...
    return true
}

then, once the Injection III app is running, we have to open our project in it so it can track any changes in our files.

Re-run your app, and you should see something like:

💉 Injection connected 👍
💉 Watching /Users/Fran/Development/HotSwapp/**

That means that your app is ready to handle code injection at runtime, let’s give it a go. Without stopping the app, change the label text color and save it.

Your Xcode output will display something like:

💉 *** Compiling /Users/Fran/Development/HotSwapp/HotSwapp/ViewController.swift ***
💉 Loading .dylib ...
objc[7606]: Class _TtC8HotSwapp14ViewController is implemented in both /Users/Fran/Library/Developer/CoreSimulator/Devices/5625C398-4862-4C4E-A5AF-E51A78D1113F/data/Containers/Bundle/Application/BDCBDDA4-A09B-4D72-8048-C24FF1193279/HotSwapp.app/HotSwapp (0x101d72a10) and /Users/Fran/Library/Containers/com.johnholdsworth.InjectionIII/Data/eval101.dylib (0x104b19278). One of the two will be used. Which one is undefined.
💉 Loaded .dylib - Ignore any duplicate class warning ^
💉 Injected 'ViewController'

But your app label keeps having the same color, what’s going on?

Your app has a new code, but you have to respond to that change. Create a new file, called it UIViewController+HotSwap.swift and add this content:

import UIKit

#if DEBUG
    extension UIViewController {
        @objc func injected() {
            for subview in view.subviews {
                subview.removeFromSuperview()
            }
            if let sublayers = self.view.layer.sublayers {
                for sublayer in sublayers {
                    sublayer.removeFromSuperlayer()
                }
            }

            viewDidLoad()
        }
    }
#endif

What this method is doing is removing all views and layers from your view controller and will invoke the viewDidLoad method again. Stop your app, and rerun it, now it will show the new color.

Now, change the label color and save it.

🎉🎉🎉

Without stopping it, replace one of the constraints to adjust the label to the left border. Once you save it, in one second, the UI will be reflecting that change.

Now imagine that instead of this app, how this could improve your development speed in some scenarios with a big app, with thousands of lines of code with a lot of third parties dependencies.

iOS UI development, ludicrously fast.

Our experience so far.

After using this for a few weeks, we would like to share with you what we’ve learned about this so you can get up to speed without making the same mistakes we did.

  • Check the documentation from the project.
  • This does not work well when there are new methods or properties; in those cases, rebuild the whole app. What we do is define upfront the methods we are going to need, and then we fill them with the logic.
  • Do not create your views outside the viewDidLoad method; otherwise after the first run, the UI could end up in an invalid state. Keep this in mind, viewDidLoad should init every view and their constraints.
  • You cannot use this on a real device.
  • Code swapping does not get along code coverage, so we recommend you to keep a different scheme for the usage of Injection III while you are fine-tuning your UI.

References

Photo by Jean Gerber on Unsplash

Continue ReadingiOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

One of the biggest complaints you can find between iOS developers is that sometimes, the feedback loop you have when you are doing some fine-tuning of the UI is long. It produces a new Swift compilation, creates a new binary, then the app gets deployed to the simulator, once that’s done, the system will start the app, and then you will be able to navigate to the right screen to check if those small changes are ok.

Sounds familiar?

Meanwhile, you can see your colleges developing websites or React Native apps that they get feedback almost immediately, and they can even modify the UI with a designer in “real-time.”

Feel any envy yet?

What if I tell you that in iOS, we can achieve something similar to that with almost no effort? Would you believe me?

In Karumi, we’ve been playing a bit with a tool that will help us to hot-swap our code so we can shrink our feedback loop duration to just a couple of seconds.

Injection III to the rescue.

This tool created by John Holdsworth will be the one doing all the magic under the hood; it will be checking which files are being changed, compile them, and dynamically insert that code in your running app. Let’s create a tiny example so we can test how this works.

First, we need to install this app from the AppStore and run it.

HotSwapp.

So, let’s create a brand new iOS project, a “Single View App” with Swift and Storyboards, nothing fancy.

Although Injection III has no issues with Storyboards and xibs, I do ( 😬 ), so let’s get rid of the main storyboard and modify our ViewController to contain a label center on the screen.

Now it’s time to setup Injection III to be able to edit our label in real-time.

First, we have to load a bundle into our app that will help us with the method swizzling. In our AppDelegate we will add the following lines:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         ...
    #if DEBUG
        Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
     #endif
        ...
    return true
}

then, once the Injection III app is running, we have to open our project in it so it can track any changes in our files.

Re-run your app, and you should see something like:

💉 Injection connected 👍
💉 Watching /Users/Fran/Development/HotSwapp/**

That means that your app is ready to handle code injection at runtime, let’s give it a go. Without stopping the app, change the label text color and save it.

Your Xcode output will display something like:

💉 *** Compiling /Users/Fran/Development/HotSwapp/HotSwapp/ViewController.swift ***
💉 Loading .dylib ...
objc[7606]: Class _TtC8HotSwapp14ViewController is implemented in both /Users/Fran/Library/Developer/CoreSimulator/Devices/5625C398-4862-4C4E-A5AF-E51A78D1113F/data/Containers/Bundle/Application/BDCBDDA4-A09B-4D72-8048-C24FF1193279/HotSwapp.app/HotSwapp (0x101d72a10) and /Users/Fran/Library/Containers/com.johnholdsworth.InjectionIII/Data/eval101.dylib (0x104b19278). One of the two will be used. Which one is undefined.
💉 Loaded .dylib - Ignore any duplicate class warning ^
💉 Injected 'ViewController'

But your app label keeps having the same color, what’s going on?

Your app has a new code, but you have to respond to that change. Create a new file, called it UIViewController+HotSwap.swift and add this content:

import UIKit

#if DEBUG
    extension UIViewController {
        @objc func injected() {
            for subview in view.subviews {
                subview.removeFromSuperview()
            }
            if let sublayers = self.view.layer.sublayers {
                for sublayer in sublayers {
                    sublayer.removeFromSuperlayer()
                }
            }

            viewDidLoad()
        }
    }
#endif

What this method is doing is removing all views and layers from your view controller and will invoke the viewDidLoad method again. Stop your app, and rerun it, now it will show the new color.

Now, change the label color and save it.

🎉🎉🎉

Without stopping it, replace one of the constraints to adjust the label to the left border. Once you save it, in one second, the UI will be reflecting that change.

Now imagine that instead of this app, how this could improve your development speed in some scenarios with a big app, with thousands of lines of code with a lot of third parties dependencies.

iOS UI development, ludicrously fast.

Our experience so far.

After using this for a few weeks, we would like to share with you what we’ve learned about this so you can get up to speed without making the same mistakes we did.

  • Check the documentation from the project.
  • This does not work well when there are new methods or properties; in those cases, rebuild the whole app. What we do is define upfront the methods we are going to need, and then we fill them with the logic.
  • Do not create your views outside the viewDidLoad method; otherwise after the first run, the UI could end up in an invalid state. Keep this in mind, viewDidLoad should init every view and their constraints.
  • You cannot use this on a real device.
  • Code swapping does not get along code coverage, so we recommend you to keep a different scheme for the usage of Injection III while you are fine-tuning your UI.

References

Photo by Jean Gerber on Unsplash

Continue ReadingiOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

One of the biggest complaints you can find between iOS developers is that sometimes, the feedback loop you have when you are doing some fine-tuning of the UI is long. It produces a new Swift compilation, creates a new binary, then the app gets deployed to the simulator, once that’s done, the system will start the app, and then you will be able to navigate to the right screen to check if those small changes are ok.

Sounds familiar?

Meanwhile, you can see your colleges developing websites or React Native apps that they get feedback almost immediately, and they can even modify the UI with a designer in “real-time.”

Feel any envy yet?

What if I tell you that in iOS, we can achieve something similar to that with almost no effort? Would you believe me?

In Karumi, we’ve been playing a bit with a tool that will help us to hot-swap our code so we can shrink our feedback loop duration to just a couple of seconds.

Injection III to the rescue.

This tool created by John Holdsworth will be the one doing all the magic under the hood; it will be checking which files are being changed, compile them, and dynamically insert that code in your running app. Let’s create a tiny example so we can test how this works.

First, we need to install this app from the AppStore and run it.

HotSwapp.

So, let’s create a brand new iOS project, a “Single View App” with Swift and Storyboards, nothing fancy.

Although Injection III has no issues with Storyboards and xibs, I do ( 😬 ), so let’s get rid of the main storyboard and modify our ViewController to contain a label center on the screen.

Now it’s time to setup Injection III to be able to edit our label in real-time.

First, we have to load a bundle into our app that will help us with the method swizzling. In our AppDelegate we will add the following lines:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         ...
    #if DEBUG
        Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
     #endif
        ...
    return true
}

then, once the Injection III app is running, we have to open our project in it so it can track any changes in our files.

Re-run your app, and you should see something like:

💉 Injection connected 👍
💉 Watching /Users/Fran/Development/HotSwapp/**

That means that your app is ready to handle code injection at runtime, let’s give it a go. Without stopping the app, change the label text color and save it.

Your Xcode output will display something like:

💉 *** Compiling /Users/Fran/Development/HotSwapp/HotSwapp/ViewController.swift ***
💉 Loading .dylib ...
objc[7606]: Class _TtC8HotSwapp14ViewController is implemented in both /Users/Fran/Library/Developer/CoreSimulator/Devices/5625C398-4862-4C4E-A5AF-E51A78D1113F/data/Containers/Bundle/Application/BDCBDDA4-A09B-4D72-8048-C24FF1193279/HotSwapp.app/HotSwapp (0x101d72a10) and /Users/Fran/Library/Containers/com.johnholdsworth.InjectionIII/Data/eval101.dylib (0x104b19278). One of the two will be used. Which one is undefined.
💉 Loaded .dylib - Ignore any duplicate class warning ^
💉 Injected 'ViewController'

But your app label keeps having the same color, what’s going on?

Your app has a new code, but you have to respond to that change. Create a new file, called it UIViewController+HotSwap.swift and add this content:

import UIKit

#if DEBUG
    extension UIViewController {
        @objc func injected() {
            for subview in view.subviews {
                subview.removeFromSuperview()
            }
            if let sublayers = self.view.layer.sublayers {
                for sublayer in sublayers {
                    sublayer.removeFromSuperlayer()
                }
            }

            viewDidLoad()
        }
    }
#endif

What this method is doing is removing all views and layers from your view controller and will invoke the viewDidLoad method again. Stop your app, and rerun it, now it will show the new color.

Now, change the label color and save it.

🎉🎉🎉

Without stopping it, replace one of the constraints to adjust the label to the left border. Once you save it, in one second, the UI will be reflecting that change.

Now imagine that instead of this app, how this could improve your development speed in some scenarios with a big app, with thousands of lines of code with a lot of third parties dependencies.

iOS UI development, ludicrously fast.

Our experience so far.

After using this for a few weeks, we would like to share with you what we’ve learned about this so you can get up to speed without making the same mistakes we did.

  • Check the documentation from the project.
  • This does not work well when there are new methods or properties; in those cases, rebuild the whole app. What we do is define upfront the methods we are going to need, and then we fill them with the logic.
  • Do not create your views outside the viewDidLoad method; otherwise after the first run, the UI could end up in an invalid state. Keep this in mind, viewDidLoad should init every view and their constraints.
  • You cannot use this on a real device.
  • Code swapping does not get along code coverage, so we recommend you to keep a different scheme for the usage of Injection III while you are fine-tuning your UI.

References

Photo by Jean Gerber on Unsplash

Continue ReadingiOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

iOS UI development, ludicrously fast.

One of the biggest complaints you can find between iOS developers is that sometimes, the feedback loop you have when you are doing some fine-tuning of the UI is long. It produces a new Swift compilation, creates a new binary, then the app gets deployed to the simulator, once that’s done, the system will start the app, and then you will be able to navigate to the right screen to check if those small changes are ok.

Sounds familiar?

Meanwhile, you can see your colleges developing websites or React Native apps that they get feedback almost immediately, and they can even modify the UI with a designer in “real-time.”

Feel any envy yet?

What if I tell you that in iOS, we can achieve something similar to that with almost no effort? Would you believe me?

In Karumi, we’ve been playing a bit with a tool that will help us to hot-swap our code so we can shrink our feedback loop duration to just a couple of seconds.

Injection III to the rescue.

This tool created by John Holdsworth will be the one doing all the magic under the hood; it will be checking which files are being changed, compile them, and dynamically insert that code in your running app. Let’s create a tiny example so we can test how this works.

First, we need to install this app from the AppStore and run it.

HotSwapp.

So, let’s create a brand new iOS project, a “Single View App” with Swift and Storyboards, nothing fancy.

Although Injection III has no issues with Storyboards and xibs, I do ( 😬 ), so let’s get rid of the main storyboard and modify our ViewController to contain a label center on the screen.

Now it’s time to setup Injection III to be able to edit our label in real-time.

First, we have to load a bundle into our app that will help us with the method swizzling. In our AppDelegate we will add the following lines:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         ...
    #if DEBUG
        Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
     #endif
        ...
    return true
}

then, once the Injection III app is running, we have to open our project in it so it can track any changes in our files.

Re-run your app, and you should see something like:

💉 Injection connected 👍
💉 Watching /Users/Fran/Development/HotSwapp/**

That means that your app is ready to handle code injection at runtime, let’s give it a go. Without stopping the app, change the label text color and save it.

Your Xcode output will display something like:

💉 *** Compiling /Users/Fran/Development/HotSwapp/HotSwapp/ViewController.swift ***
💉 Loading .dylib ...
objc[7606]: Class _TtC8HotSwapp14ViewController is implemented in both /Users/Fran/Library/Developer/CoreSimulator/Devices/5625C398-4862-4C4E-A5AF-E51A78D1113F/data/Containers/Bundle/Application/BDCBDDA4-A09B-4D72-8048-C24FF1193279/HotSwapp.app/HotSwapp (0x101d72a10) and /Users/Fran/Library/Containers/com.johnholdsworth.InjectionIII/Data/eval101.dylib (0x104b19278). One of the two will be used. Which one is undefined.
💉 Loaded .dylib - Ignore any duplicate class warning ^
💉 Injected 'ViewController'

But your app label keeps having the same color, what’s going on?

Your app has a new code, but you have to respond to that change. Create a new file, called it UIViewController+HotSwap.swift and add this content:

import UIKit

#if DEBUG
    extension UIViewController {
        @objc func injected() {
            for subview in view.subviews {
                subview.removeFromSuperview()
            }
            if let sublayers = self.view.layer.sublayers {
                for sublayer in sublayers {
                    sublayer.removeFromSuperlayer()
                }
            }

            viewDidLoad()
        }
    }
#endif

What this method is doing is removing all views and layers from your view controller and will invoke the viewDidLoad method again. Stop your app, and rerun it, now it will show the new color.

Now, change the label color and save it.

🎉🎉🎉

Without stopping it, replace one of the constraints to adjust the label to the left border. Once you save it, in one second, the UI will be reflecting that change.

Now imagine that instead of this app, how this could improve your development speed in some scenarios with a big app, with thousands of lines of code with a lot of third parties dependencies.

iOS UI development, ludicrously fast.

Our experience so far.

After using this for a few weeks, we would like to share with you what we’ve learned about this so you can get up to speed without making the same mistakes we did.

  • Check the documentation from the project.
  • This does not work well when there are new methods or properties; in those cases, rebuild the whole app. What we do is define upfront the methods we are going to need, and then we fill them with the logic.
  • Do not create your views outside the viewDidLoad method; otherwise after the first run, the UI could end up in an invalid state. Keep this in mind, viewDidLoad should init every view and their constraints.
  • You cannot use this on a real device.
  • Code swapping does not get along code coverage, so we recommend you to keep a different scheme for the usage of Injection III while you are fine-tuning your UI.

References

Photo by Jean Gerber on Unsplash

Continue ReadingiOS UI development, ludicrously fast.

Lambda World 2019

Lambda World 2019

2019 is the fifth year in a row that a functional programming event is gathering more than 600 people. In the beautiful city of Cádiz. All here to learn about this remarkable coding paradigm. If you couldn’t attend or you want to know about our experience in this event, keep reading. 👇

Lambda World 2019

This year, Jorge and I were in Cádiz since the very first day. The schedule for the Thursday event was exciting. During the morning, an unconference where anyone could propose a lighting talk took place. It was super interesting to see how awesome developers from many different companies decided to talk about topics like:

For me, the most interesting part was the talk by Tapio, where he reviewed how using type classes, we can code generic pure functional programs.

After the unconference, we decided it was time to type and move our fingers, so we went to the workshops. We decided to go to two workshops with different topics, the first one about testing, and the second one about how to build micro-services using a tool named Mu.

The first one was just theory. We had no time to code, but we reviewed how, using property-based testing, we could create programs to test our programs using randomly generated data. The workshop’s host, Adam Rosien, did it great explaining every single detail related to the usage of Scala Check and the most important part: how to think about your software properties. If you don’t know what’s property-based testing about we recommend you to read our blog post series about it.

The second one was breathtaking. Adrián Ramirez and Pepe García explained during almost 2 hours how using an Avro or Open API definition, they could generate a client and a server for the described service using GRPC and basing the implementation on tagless final 🤯. They used mu, a tool 47 Degrees is actively developing, which is designed to create purely functional micro-services. It was interesting to see how the generation of client and server of the micro-service they were building was really similar to the API client generations we’ve been using for a lot of our projects.

Lambda World 2019

After the workshops, we only had left the first keynote of the event. Martin Odersky explained how the implicits feature in Scala is going to be in the next Scala version. It was awesome to see how the creator of the language reviewed the mistakes they made when implementing implicits at the very beginning, the usage of this powerful tool, and how they’ve proposed a different implementation for Scala 3 trying to solve the main pain points. It was mind-blowing when Martin showed us the analytics of the implicits feature usage in Scala projects. 98% of the Scala software uses them!!! 😱

Lambda World 2019

This was just the first day 😱. Bear with us, the second day got way better!

The second day of this conference was full of talks. From Category Theory to an awesome review of how effects are implemented in functional programming. These are the talks we attend during the second day:

Lambda World 2019

There are interesting details for all of them, but we’d like to review a bunch of these talks:

  • Optimising your code with math by April Gonçalves showed us how advanced math concepts are handy when coding. April showed how, using category theory and equational reasoning, we can write better code. Who said maths weren’t needed?
  • Arrow Meta talk, by Raúl Raja and Simon Vergauwen, was also a game-changing talk. The introduction to the new Arrow component just shown us how the life of Kotlin developers is going to change from now on. Thanks to the meta-programming library they’ve built, any developer will be able to change the way kotlin works, providing awesome support for the IntelliJ IDEA IDEs by just using Gradle Compiler Plugins. This is awesome for FP devs, but also interesting for OOP developers. Take a look at this thread with some info about it.
  • Robert M. Avram just surprised every attendee with an excellent story about the effects management in functional programming. His talk was so detailed, and the way the information was delivered was just astonishing. Take a look at this short video, please.

After the closing keynote, the talks day was over, and we only had left one thing. The awesome closing party!! We went to Santa Catalina’s Castle to have fun with friends and talk about the conference.

Lambda World 2019

Overall, Lambda World is an awesome event if you want to learn about Functional Programming. The city where the event is organized is beautiful, the organization takes care of every detail, and the level of the speakers and the talks is world-class. For the next year we’d love to see more talks related to the application of functional programming in the industry or how FP is used to solve a concrete problem, should we send a talk proposal for the next year? 🤔 Who knows, maybe we are the speakers in the next edition! We hope we’ll see you all in the 6th Lambda World edition. 🤘

Continue ReadingLambda World 2019

Lambda World 2019

Lambda World 2019

2019 is the fifth year in a row that a functional programming event is gathering more than 600 people. In the beautiful city of Cádiz. All here to learn about this remarkable coding paradigm. If you couldn’t attend or you want to know about our experience in this event, keep reading. 👇

Lambda World 2019

This year, Jorge and I were in Cádiz since the very first day. The schedule for the Thursday event was exciting. During the morning, an unconference where anyone could propose a lighting talk took place. It was super interesting to see how awesome developers from many different companies decided to talk about topics like:

For me, the most interesting part was the talk by Tapio, where he reviewed how using type classes, we can code generic pure functional programs.

After the unconference, we decided it was time to type and move our fingers, so we went to the workshops. We decided to go to two workshops with different topics, the first one about testing, and the second one about how to build micro-services using a tool named Mu.

The first one was just theory. We had no time to code, but we reviewed how, using property-based testing, we could create programs to test our programs using randomly generated data. The workshop’s host, Adam Rosien, did it great explaining every single detail related to the usage of Scala Check and the most important part: how to think about your software properties. If you don’t know what’s property-based testing about we recommend you to read our blog post series about it.

The second one was breathtaking. Adrián Ramirez and Pepe García explained during almost 2 hours how using an Avro or Open API definition, they could generate a client and a server for the described service using GRPC and basing the implementation on tagless final 🤯. They used mu, a tool 47 Degrees is actively developing, which is designed to create purely functional micro-services. It was interesting to see how the generation of client and server of the micro-service they were building was really similar to the API client generations we’ve been using for a lot of our projects.

Lambda World 2019

After the workshops, we only had left the first keynote of the event. Martin Odersky explained how the implicits feature in Scala is going to be in the next Scala version. It was awesome to see how the creator of the language reviewed the mistakes they made when implementing implicits at the very beginning, the usage of this powerful tool, and how they’ve proposed a different implementation for Scala 3 trying to solve the main pain points. It was mind-blowing when Martin showed us the analytics of the implicits feature usage in Scala projects. 98% of the Scala software uses them!!! 😱

Lambda World 2019

This was just the first day 😱. Bear with us, the second day got way better!

The second day of this conference was full of talks. From Category Theory to an awesome review of how effects are implemented in functional programming. These are the talks we attend during the second day:

Lambda World 2019

There are interesting details for all of them, but we’d like to review a bunch of these talks:

  • Optimising your code with math by April Gonçalves showed us how advanced math concepts are handy when coding. April showed how, using category theory and equational reasoning, we can write better code. Who said maths weren’t needed?
  • Arrow Meta talk, by Raúl Raja and Simon Vergauwen, was also a game-changing talk. The introduction to the new Arrow component just shown us how the life of Kotlin developers is going to change from now on. Thanks to the meta-programming library they’ve built, any developer will be able to change the way kotlin works, providing awesome support for the IntelliJ IDEA IDEs by just using Gradle Compiler Plugins. This is awesome for FP devs, but also interesting for OOP developers. Take a look at this thread with some info about it.
  • Robert M. Avram just surprised every attendee with an excellent story about the effects management in functional programming. His talk was so detailed, and the way the information was delivered was just astonishing. Take a look at this short video, please.

After the closing keynote, the talks day was over, and we only had left one thing. The awesome closing party!! We went to Santa Catalina’s Castle to have fun with friends and talk about the conference.

Lambda World 2019

Overall, Lambda World is an awesome event if you want to learn about Functional Programming. The city where the event is organized is beautiful, the organization takes care of every detail, and the level of the speakers and the talks is world-class. For the next year we’d love to see more talks related to the application of functional programming in the industry or how FP is used to solve a concrete problem, should we send a talk proposal for the next year? 🤔 Who knows, maybe we are the speakers in the next edition! We hope we’ll see you all in the 6th Lambda World edition. 🤘

Continue ReadingLambda World 2019

Lambda World 2019

Lambda World 2019

2019 is the fifth year in a row that a functional programming event is gathering more than 600 people. In the beautiful city of Cádiz. All here to learn about this remarkable coding paradigm. If you couldn’t attend or you want to know about our experience in this event, keep reading. 👇

Lambda World 2019

This year, Jorge and I were in Cádiz since the very first day. The schedule for the Thursday event was exciting. During the morning, an unconference where anyone could propose a lighting talk took place. It was super interesting to see how awesome developers from many different companies decided to talk about topics like:

For me, the most interesting part was the talk by Tapio, where he reviewed how using type classes, we can code generic pure functional programs.

After the unconference, we decided it was time to type and move our fingers, so we went to the workshops. We decided to go to two workshops with different topics, the first one about testing, and the second one about how to build micro-services using a tool named Mu.

The first one was just theory. We had no time to code, but we reviewed how, using property-based testing, we could create programs to test our programs using randomly generated data. The workshop’s host, Adam Rosien, did it great explaining every single detail related to the usage of Scala Check and the most important part: how to think about your software properties. If you don’t know what’s property-based testing about we recommend you to read our blog post series about it.

The second one was breathtaking. Adrián Ramirez and Pepe García explained during almost 2 hours how using an Avro or Open API definition, they could generate a client and a server for the described service using GRPC and basing the implementation on tagless final 🤯. They used mu, a tool 47 Degrees is actively developing, which is designed to create purely functional micro-services. It was interesting to see how the generation of client and server of the micro-service they were building was really similar to the API client generations we’ve been using for a lot of our projects.

Lambda World 2019

After the workshops, we only had left the first keynote of the event. Martin Odersky explained how the implicits feature in Scala is going to be in the next Scala version. It was awesome to see how the creator of the language reviewed the mistakes they made when implementing implicits at the very beginning, the usage of this powerful tool, and how they’ve proposed a different implementation for Scala 3 trying to solve the main pain points. It was mind-blowing when Martin showed us the analytics of the implicits feature usage in Scala projects. 98% of the Scala software uses them!!! 😱

Lambda World 2019

This was just the first day 😱. Bear with us, the second day got way better!

The second day of this conference was full of talks. From Category Theory to an awesome review of how effects are implemented in functional programming. These are the talks we attend during the second day:

Lambda World 2019

There are interesting details for all of them, but we’d like to review a bunch of these talks:

  • Optimising your code with math by April Gonçalves showed us how advanced math concepts are handy when coding. April showed how, using category theory and equational reasoning, we can write better code. Who said maths weren’t needed?
  • Arrow Meta talk, by Raúl Raja and Simon Vergauwen, was also a game-changing talk. The introduction to the new Arrow component just shown us how the life of Kotlin developers is going to change from now on. Thanks to the meta-programming library they’ve built, any developer will be able to change the way kotlin works, providing awesome support for the IntelliJ IDEA IDEs by just using Gradle Compiler Plugins. This is awesome for FP devs, but also interesting for OOP developers. Take a look at this thread with some info about it.
  • Robert M. Avram just surprised every attendee with an excellent story about the effects management in functional programming. His talk was so detailed, and the way the information was delivered was just astonishing. Take a look at this short video, please.

After the closing keynote, the talks day was over, and we only had left one thing. The awesome closing party!! We went to Santa Catalina’s Castle to have fun with friends and talk about the conference.

Lambda World 2019

Overall, Lambda World is an awesome event if you want to learn about Functional Programming. The city where the event is organized is beautiful, the organization takes care of every detail, and the level of the speakers and the talks is world-class. For the next year we’d love to see more talks related to the application of functional programming in the industry or how FP is used to solve a concrete problem, should we send a talk proposal for the next year? 🤔 Who knows, maybe we are the speakers in the next edition! We hope we’ll see you all in the 6th Lambda World edition. 🤘

Continue ReadingLambda World 2019

Lambda World 2019

Lambda World 2019

2019 is the fifth year in a row that a functional programming event is gathering more than 600 people. In the beautiful city of Cádiz. All here to learn about this remarkable coding paradigm. If you couldn’t attend or you want to know about our experience in this event, keep reading. 👇

Lambda World 2019

This year, Jorge and I were in Cádiz since the very first day. The schedule for the Thursday event was exciting. During the morning, an unconference where anyone could propose a lighting talk took place. It was super interesting to see how awesome developers from many different companies decided to talk about topics like:

For me, the most interesting part was the talk by Tapio, where he reviewed how using type classes, we can code generic pure functional programs.

After the unconference, we decided it was time to type and move our fingers, so we went to the workshops. We decided to go to two workshops with different topics, the first one about testing, and the second one about how to build micro-services using a tool named Mu.

The first one was just theory. We had no time to code, but we reviewed how, using property-based testing, we could create programs to test our programs using randomly generated data. The workshop’s host, Adam Rosien, did it great explaining every single detail related to the usage of Scala Check and the most important part: how to think about your software properties. If you don’t know what’s property-based testing about we recommend you to read our blog post series about it.

The second one was breathtaking. Adrián Ramirez and Pepe García explained during almost 2 hours how using an Avro or Open API definition, they could generate a client and a server for the described service using GRPC and basing the implementation on tagless final 🤯. They used mu, a tool 47 Degrees is actively developing, which is designed to create purely functional micro-services. It was interesting to see how the generation of client and server of the micro-service they were building was really similar to the API client generations we’ve been using for a lot of our projects.

Lambda World 2019

After the workshops, we only had left the first keynote of the event. Martin Odersky explained how the implicits feature in Scala is going to be in the next Scala version. It was awesome to see how the creator of the language reviewed the mistakes they made when implementing implicits at the very beginning, the usage of this powerful tool, and how they’ve proposed a different implementation for Scala 3 trying to solve the main pain points. It was mind-blowing when Martin showed us the analytics of the implicits feature usage in Scala projects. 98% of the Scala software uses them!!! 😱

Lambda World 2019

This was just the first day 😱. Bear with us, the second day got way better!

The second day of this conference was full of talks. From Category Theory to an awesome review of how effects are implemented in functional programming. These are the talks we attend during the second day:

Lambda World 2019

There are interesting details for all of them, but we’d like to review a bunch of these talks:

  • Optimising your code with math by April Gonçalves showed us how advanced math concepts are handy when coding. April showed how, using category theory and equational reasoning, we can write better code. Who said maths weren’t needed?
  • Arrow Meta talk, by Raúl Raja and Simon Vergauwen, was also a game-changing talk. The introduction to the new Arrow component just shown us how the life of Kotlin developers is going to change from now on. Thanks to the meta-programming library they’ve built, any developer will be able to change the way kotlin works, providing awesome support for the IntelliJ IDEA IDEs by just using Gradle Compiler Plugins. This is awesome for FP devs, but also interesting for OOP developers. Take a look at this thread with some info about it.
  • Robert M. Avram just surprised every attendee with an excellent story about the effects management in functional programming. His talk was so detailed, and the way the information was delivered was just astonishing. Take a look at this short video, please.

After the closing keynote, the talks day was over, and we only had left one thing. The awesome closing party!! We went to Santa Catalina’s Castle to have fun with friends and talk about the conference.

Lambda World 2019

Overall, Lambda World is an awesome event if you want to learn about Functional Programming. The city where the event is organized is beautiful, the organization takes care of every detail, and the level of the speakers and the talks is world-class. For the next year we’d love to see more talks related to the application of functional programming in the industry or how FP is used to solve a concrete problem, should we send a talk proposal for the next year? 🤔 Who knows, maybe we are the speakers in the next edition! We hope we’ll see you all in the 6th Lambda World edition. 🤘

Continue ReadingLambda World 2019

Lambda World 2019

Lambda World 2019

2019 is the fifth year in a row that a functional programming event is gathering more than 600 people. In the beautiful city of Cádiz. All here to learn about this remarkable coding paradigm. If you couldn’t attend or you want to know about our experience in this event, keep reading. 👇

Lambda World 2019

This year, Jorge and I were in Cádiz since the very first day. The schedule for the Thursday event was exciting. During the morning, an unconference where anyone could propose a lighting talk took place. It was super interesting to see how awesome developers from many different companies decided to talk about topics like:

For me, the most interesting part was the talk by Tapio, where he reviewed how using type classes, we can code generic pure functional programs.

After the unconference, we decided it was time to type and move our fingers, so we went to the workshops. We decided to go to two workshops with different topics, the first one about testing, and the second one about how to build micro-services using a tool named Mu.

The first one was just theory. We had no time to code, but we reviewed how, using property-based testing, we could create programs to test our programs using randomly generated data. The workshop’s host, Adam Rosien, did it great explaining every single detail related to the usage of Scala Check and the most important part: how to think about your software properties. If you don’t know what’s property-based testing about we recommend you to read our blog post series about it.

The second one was breathtaking. Adrián Ramirez and Pepe García explained during almost 2 hours how using an Avro or Open API definition, they could generate a client and a server for the described service using GRPC and basing the implementation on tagless final 🤯. They used mu, a tool 47 Degrees is actively developing, which is designed to create purely functional micro-services. It was interesting to see how the generation of client and server of the micro-service they were building was really similar to the API client generations we’ve been using for a lot of our projects.

Lambda World 2019

After the workshops, we only had left the first keynote of the event. Martin Odersky explained how the implicits feature in Scala is going to be in the next Scala version. It was awesome to see how the creator of the language reviewed the mistakes they made when implementing implicits at the very beginning, the usage of this powerful tool, and how they’ve proposed a different implementation for Scala 3 trying to solve the main pain points. It was mind-blowing when Martin showed us the analytics of the implicits feature usage in Scala projects. 98% of the Scala software uses them!!! 😱

Lambda World 2019

This was just the first day 😱. Bear with us, the second day got way better!

The second day of this conference was full of talks. From Category Theory to an awesome review of how effects are implemented in functional programming. These are the talks we attend during the second day:

Lambda World 2019

There are interesting details for all of them, but we’d like to review a bunch of these talks:

  • Optimising your code with math by April Gonçalves showed us how advanced math concepts are handy when coding. April showed how, using category theory and equational reasoning, we can write better code. Who said maths weren’t needed?
  • Arrow Meta talk, by Raúl Raja and Simon Vergauwen, was also a game-changing talk. The introduction to the new Arrow component just shown us how the life of Kotlin developers is going to change from now on. Thanks to the meta-programming library they’ve built, any developer will be able to change the way kotlin works, providing awesome support for the IntelliJ IDEA IDEs by just using Gradle Compiler Plugins. This is awesome for FP devs, but also interesting for OOP developers. Take a look at this thread with some info about it.
  • Robert M. Avram just surprised every attendee with an excellent story about the effects management in functional programming. His talk was so detailed, and the way the information was delivered was just astonishing. Take a look at this short video, please.

After the closing keynote, the talks day was over, and we only had left one thing. The awesome closing party!! We went to Santa Catalina’s Castle to have fun with friends and talk about the conference.

Lambda World 2019

Overall, Lambda World is an awesome event if you want to learn about Functional Programming. The city where the event is organized is beautiful, the organization takes care of every detail, and the level of the speakers and the talks is world-class. For the next year we’d love to see more talks related to the application of functional programming in the industry or how FP is used to solve a concrete problem, should we send a talk proposal for the next year? 🤔 Who knows, maybe we are the speakers in the next edition! We hope we’ll see you all in the 6th Lambda World edition. 🤘

Continue ReadingLambda World 2019

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 ReadingShared 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 ReadingShared 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 ReadingShared Library in Kotlin Multiplatform

End of content

No more pages to load