Back Copy 3 back

How to boost your switch to Flutter? Guidelines from an iOS developer

Mariana Janevska May 12, 2023
share this on

Today, we will share Medium post from our Mobile Tech Lead, Mariana Janevska.

I have been interested in Flutter for a while and I can honestly say I am pleasantly surprised with what this framework can do. I now have two successfully finished Flutter applications for both iOS and Android 🥳, one on App Store and Google Play, one in development, and one public template I contribute to. I learned a thing or two so far, but I do have a lot more to learn.

Needless to say, developing apps with Flutter and Dart is different than developing iOS applications. Here is a quick summary of my experience with transitioning to Flutter.

Note: this article shows my perspective compared to what I am used to in iOS development.

Let’s start from the beginning:

1. Installation and setup

Installation is pretty straightforward if you follow the official documentation:

As for the IDE, you can choose between Android Studio or VS Code. I chose Android Studio since I was already familiar with it and so far it seems pretty good, with regular updates for the Flutter plugin. But to be honest, I am considering switching to VSCode just so I can use Github Copilot 😀

2. Flutter and Dart

The first thing you should do once you get the setup ready is to go through the language tour. I tried doing the tutorials with only a brief introduction to Dart, but I noticed I wasn’t familiar with a bunch of Dart concepts and syntax. Once I got through the entire tour, the tutorials got a lot easier. I have to say I needed quite some time to get used to Dart since in my opinion is not really similar to Swift. It’s actually quite closer to Java and C#. I still kinda like Swift more 💞.

You can use DartPad to play around with Dart’s language features and get used to adding a ‘;’ after every line of code.

And if you, like me, are wondering why Flutter and Dart, read this article.

3. Start simple

Next, dig into the documentation. While you do that, you can also try using Flutter Studio for playing around with the UI and seeing the code being generated as you drag & drop items to the screen.

The Flutter team did an excellent job of documenting Flutter and Dart. Additionally, they even have separate onboarding sections for iOS and Android devs! Do not skip those!

4. Several tutorials later…

After going through the documentation, the cookbooks, and the codelabs I started feeling a little more confident, but I also had a bunch of questions. Like, a ton.

Widgets lifecycle? App lifecycle? What should be the best project structure? 
Reusable components? How do I use platform channels? 
How do I structure my networking layer? 
Where are MVC, MVP, MVVM? Redux?? BLoC??? …
How I felt after doing the Hello World example and all these questions arose.


5. Answering my questions (and hopefully yours)

Application lifecycle

Let’s start with the app lifecycle. You can subscribe to observe the lifecycle state from the widgets layer, by using WidgetsBindingObserver. When the state changes, you can get one of the following values for AppLifecycleState :

  • AppLifecycleState.resumed: The application is visible and responding to user input.
  • AppLifecycleState.inactive: The application is in an inactive state and is not receiving user input. This may mean that there is a phone call happening, the lock screen is presented, etc.
  • AppLifecycleState.paused: The app is running in the background and not currently visible to the user.
  • AppLifecycleState.detached: The application is still hosted on a flutter engine but is detached from any host views.

Ok, not bad 😀

Widgets, states, and reusability

For the widgets on the other hand, first I needed to understand the difference between the two types of widgets that Flutter has — stateless and stateful widgets.

Stateless widgets are the ones that never change. The stateful widgets, on the other hand, are dynamic (ex. they can change their appearance in response to events) and have a couple of methods that are invoked when the widget state changes:

  • createState() — creating a fresh State object, called multiple times over the lifetime
  • initState() — when the object is inserted into the tree
  • didChangeDependencies()
  • build() — every time the widget is rebuilt
  • didUpdateWidget() — when the widget configuration changes
  • setState() — notify the framework that the internal state of this object has changed
  • deactivate() — when the object is removed from the tree
  • dispose() — when the object is removed from the tree permanently
How I felt writing my first flutter app.


Speaking of trees and widgets, you will reach a point where your tree might look something similar to this:

Example widget tree


It is becoming obvious that you need to reuse some components. What really helped me here is the option for extracting widgets in Android Studio: Select parent widget ▸ Right click ▸ Refactor ▸ Extract ▸ Extract Flutter Widget

And just like that, you now have a custom widget. Android Studio automatically created a new widget from the selected one and its descendant widgets.


In Flutter, screens and pages are called routes. In iOS, a route is equivalent to a ViewController. In Flutter, a route is just a widget. There are multiple options to choose from and a couple of different ways to implement routing, so you need to go with one that suits your project needs best.

Project structure

When you work on something specific for a couple of years, structuring the project comes “naturally”. Starting a new project in a technology that you are not familiar with and that is a bit different than what you are used to can be challenging.

When you create a Flutter project, this is the initial structure of the application:

  • lib/ — contains all code
  • pubspec.yml — same as Podfile — where you list all your dependencies
  • test/ — all your tests go here
  • ios/ & android/ — the code specific for each platform, plus app icons, permission keys and localizations, Firebase-related setup (like Google-Services.json), etc.

The troublesome part is organizing your files inside the /lib folder.

This blog post is one of the most useful explanations of how to structure your project. It explores two common approaches for structuring a project: feature-first and layer-first. I, personally, prefer the layer-first approach. I do however make modifications based on the project’s needs.

After trying out different approaches and suggestions, I found that this structure works for me for almost all projects:

My preferred project structure


As for organizing the feature folders, in most of the projects we use BloC and Cubit and this kinda dictates how we structure things:

Organizing a feature folder


Now, I’m not saying this is the best approach, it’s just the one I like the most. Remember that at the end of the day, you can and should choose what works for you the best.

6. iOS vs. Flutter comparison

Both platforms have their pros and cons. And the decision of which platform should you use is based on what application you need to develop.

Flutter is cheaper and easier to maintain (single codebase). It has a quicker time to market and hot reload⚡ which is awesome and really speeds up development time.

iOS has an impeccable UX, excellent performance, and smaller app size. Excellent for high-functioning applications with complex structures.

There are a bunch of articles out there that do a details comparison between the two. I’ll leave links for a couple of them below in case you want to read more.

7. Google guides

Google devs worked hard on creating resources for #Swift developers to get started with #Flutter and #Dart. You can check them out on these links:

-Learning Flutter as a SwiftUI Developer

-Learning Dart as a Swift Developer

-Flutter / Dart vs Swift concurrency

8. What next?

Try converting an iOS app you’ve done before to Flutter. Practicing is the best way to learn. You already know the features you need to implement and you already have the design. Plus, no tutorial can be as good or as big as a real app with real cases and problems. Once you solve them, you’re good to go!

To be honest, Flutter turned out better than I thought. I am amazed by the performance, the documentation, and the hundreds of pre-made widgets just to make a developer’s life easier. Plus, it helps to know that many developers are working on improving Flutter.

Besides my obvious affection for Swift and iOS, Flutter is really starting to grow on me.

How I felt when I got to work on another Flutter app from scratch.


Or, as this old tweet puts it:

Bonus: a bunch of articles that really helped me: