Skip to content

Instantly share code, notes, and snippets.

@krispykalsi
Last active February 15, 2024 20:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krispykalsi/8453ca566738f1d24044913a54511390 to your computer and use it in GitHub Desktop.
Save krispykalsi/8453ca566738f1d24044913a54511390 to your computer and use it in GitHub Desktop.
Google Summer of Code 2022 (@ International Catrobat Organisation) Final Report

Going Hybrid


Commencing a journey of migrating Pocket Paint to Flutter


The past couple of months have been an interesting experience. My project for Google Summer of Code was originally to refactor tests from Java to Kotlin. It changed during the community bonding period and I was excited about it.

🎭 Overview

Discussions were in motion to move to a cross-platform framework. Mainly because the iOS side of things wasn't looking so good in terms of the number of features as compared to Android. And of course, the advantage of half the team size with one codebase is good too. What next? Choosing the right hybrid framework :D

At that time, there were two viable choices: KMM (Kotlin Multiplatform Mobile) and Flutter.

In KMM, the common code (business logic and other common code) is written in Kotlin and all the UI code is written separately for both platforms in their respective native languages. Read more

This seemed like the obvious choice; the code was already there for Android and that too in Kotlin, only had to write the UI code for iOS. Well, not as simple as it sounds. Flutter was a better choice than KMM in my opinion -

  • KMM just reached alpha. Flutter for mobile has been in production for a few years now.
  • It has a large arsenal of useful packages and one of the best bunch of resources out there.
  • JIT & AOT compilation (read more is just great developer experience!

I have had work experience with Flutter before but never tried KMM. Decided to give it a try before jumping to conclusions. Made a simple drawing app (repo) that draws a hard-coded stroke on both platforms. A few thoughts -

  • Took wayyy too long for the Gradle sync and initial build to finish for a hello world app.
  • Kotlin has a nice community on Slack which proved to be quite helpful. I was having problems with generating a common API for the Color class. Searched for the relevant keywords and found a decent solution in the multiplatform channel. Good support overall.
  • Quite a few things were in the experimental phase, it sure is to change in the coming months though.
  • Since both platforms have declarative solutions for UI (Jetpack Compose for Android and SwiftUI for iOS), it was an almost as good experience as Flutter's "hot reload/restart".

The app did work in the end but going with KMM at its current stage would not be the right choice for Pocket Paint. I believe now we've established that Flutter was the way to go.

πŸ“ Planning

Since this was going to be a repository from scratch, as a true Flutter developer, I had to burn my brains out by searching for the "best" state management solution out there, haha. It's a pain to find the right one, but I chose Riverpod as my poison. It has concise documentation and also acts as a service locator on top of being an awesome state management solution.

Before explaining the project structure, I would like to define a few things mentioned in the diagram -

  • A red arrow represents the direction of dependency.

    Example: X --> Y means that X depends on Y

  • State is an immutable class of single/multiple properties that control a UI component.

    Example: In our app, we have a state called WorkspaceState that has a property isFullscreen. This property controls two parts of the UI - the exit fullscreen icon button and the app bars (bottom and top). They are hidden or shown based on the isFullscreen property.

  • UI component means parts of UI grouped such that it needs the fewest amount of state variables to control.

    The two parts of UI (exit button and app bars) mentioned in the previous point can be collectively called as a UI component.

"wow that makes no sense."

I understand, just move forward, and it'll be more clear. With that, I present my two cents' knowledge on the flow of a single UI component in our app in the following diagram -

Let's consider the following scenarios -

Tap the scenario to open

Scenario One

Situation: App starts, user taps on the fullscreen button

  1. UI component uses the notifier to invoke a function on the tap event.
  2. notifier flips some boolean property isFullscreen of some WorkspaceState to true in the function invoked in previous step. The whole state class is replaced by a new instance with the new value of isFullscreen property and rest properties are as they were before,
  3. UI component automatically rebuilds to react to the new the state.

This was a simple scenario where there is no I/O operation involved.

Scenario Two

Situation: User is done with the drawing, now they tap the save image button

  1. UI component uses the notifier to invoke a function on the tap event.
  2. notifier flips some boolean property isPerformingIOTask of some WorkspaceState to true.
  3. UI component reacts to it by showing some loading indicator.
  4. notifier uses some CommandManager to get a list of all draw commands.
  5. notifier then uses that list to generate png image using some ImageService.
  6. notifier then uses that image data to save it to a file on the device using some FileService.
  7. After the file is done saving successfully, notifier flips back isPerformingIOTask to false.
  8. UI component reacts to it by dismissing the loading indicator.

Enough talk, let's get to the code already!

🧱 Action

By the time I decided on the project structure, my mentors took some time and created this incremental list of tasks. With each task is attached the link to its Jira ticket and the relevant pull request.

πŸŒ† Epilogue

And here comes the end of my project period. But not the end of this migration journey! Although it is at a decent stage, there are still a lot of tasks left to make this app a worthy replacement for its android sibling. I plan to be consistently present during this process and help out other people to join in too.

A big thanks to Thorsten, Julia and Wolfgang for always helping me out and providing me with this opportunity πŸ™πŸΌ I am grateful to have worked with this team.

πŸ”— (More) Links

Because there are never enough links...


Hey! Thanks for reading. If you found this report/story/article interesting or might have some feedback, please do reach out ^_^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment