Lessons from the Flutter Trenches

Lots of emulator testing is not enough!

Whilst I am still learning and actually struggling more so than with any other language/framework than I've tried to get on yop of before... Flutter is brilliant for whipping up cross-platform apps! But here's the rub: what works a treat on your trusty emulator might throw a wobbly on a real phone. I thought I'd make this blog post about my recent experiences working on an app with a friend. I did loads of emulator testing, but pushing it out to a real device is where you get to see real user experience issues. Let's dive in.

Emulators: Not the be-all and end-all

Don't get me wrong, emulators are ace. They're quick, they're easy, and they let you test on all sorts of virtual setups. But they're not the whole story:

  1. Performance can be a bit dodgy (even a powerful laptop doesn't really show you what a phone can do (sometimes))
  2. Hardware quirks might not show up
  3. Real-world use? That's another kettle of fish entirely

The Authentication Screen Kerfuffle

The login screen was looking pretty swish on the emulator. But on a real phone? It was about as much use as a chocolate teapot.

Two major snags:

  1. The phone didn't twig it was a login screen, so no auto-fill.
  2. Password managers like Bitwarden were giving it the cold shoulder.

Not exactly user-friendly, is it? After a fair bit of trial and error, I cracked it:

AutofillGroup(
  child: Form(
    key: _formKey,
    child: Column(
      children: <Widget>[
        TextFormField(
          controller: _emailController,
          decoration: InputDecoration(
            hintText: 'Email',
            prefixIcon: Icon(Icons.email),
          ),
          keyboardType: TextInputType.emailAddress,
          autofillHints: [AutofillHints.email],
        ),
        TextFormField(
          controller: _passwordController,
          decoration: InputDecoration(
            hintText: 'Password',
            prefixIcon: Icon(Icons.lock),
          ),
          obscureText: true,
          autofillHints: [AutofillHints.password],
        ),
        // More widgets...
      ],
    ),
  ),
)

Wrapping the form in an AutofillGroup and adding those autofillHints? Game changer. Suddenly, the login screen was playing nice with auto-fill and password managers. #win

The Real Device Revelation

So, what have I learned from all this palaver?

  1. Platform quirks: Real devices can throw curveballs that emulators don't even see coming.
  2. User experience matters: What seems fine on an emulator might be a right pain on a real device.
  3. Performance reality check: Nothing beats a real device for seeing how your app actually performs.
  4. Hardware hiccups: Cameras, GPS, sensors - they're a whole different ball game on real hardware.
  5. OS oddities: Different phones can have their own little quirks in how they handle Android or iOS.

The Upshot

Emulators are great. They're a crucial part of the dev process. But they're not the whole story. Getting your app onto real devices, early and often, can save you a world of pain down the line.

Remember, the end users aren't running your app on an emulator, are they? They're using real phones, with all their quirks and foibles. By testing on real devices, you're not just making a better app - you're making a better experience for the people who'll actually use it.

I also recommend adding a feedback feature into any app, especially an early stage one, how best to find what real users like and don't like about the experience?