← Back to the portfolio

CASE STUDIES

Three stories from the trenches.

Anyone can list technologies. These are the situations where shipping actually got hard — a year-long fight with App Review, a chores app that crossed half a million downloads, and one codebase that had to run on six platforms at once.

The year-long App Store battle we won

CLIENT · AmediaTV / Anibla.uz DURATION · ~12 months OUTCOME · ★ 4.6, 500+ ratings

The problem

Anibla is Uzbekistan's first anime-dubbing streaming platform. The app was finished, tested and ready — and App Review would not let it through. The rejection reason was not a bug or a crash: Apple could not verify that we had the rights to the brand and the content, because the app name did not match the website domain the account was associated with.

This is the kind of rejection that quietly kills products. There is no code change that fixes it, the review thread resets with each new reviewer, and every resubmission costs another week.

What I did

  • Treated it as an evidence problem, not a code problem — assembled a documentation trail proving the app belonged to the AmediaTV brand.
  • Kept a single continuous thread with Apple Support instead of opening fresh disputes, so context accumulated instead of resetting.
  • Escalated through the proper channels and kept the client informed with realistic timelines rather than optimistic ones.
  • Shipped every other part of the product in the meantime — including a Flutter desktop build — so the business kept moving while review was blocked.

The app is live, rated 4.6 with 500+ ratings. The lesson: store approval is a relationship you manage, not a checkbox you tick — and a developer who has done it before saves you months.

Why it matters to you

If your app touches licensed content, tracking, payments, or a brand you do not own outright, review risk is a real project risk. I have been through it — including a separate migration from a personal to a business Apple Developer account for a fintech app because of tracking requirements, and an in-app-purchase dispute resolved by explaining local payment realities to Apple.

How a chores app passed 500K downloads

PRODUCT · HomeTasker iOS · ★ 4.8, 2,800+ ratings ANDROID · 500K+ installs

The problem

A household-chores app lives or dies by whether people remember it exists. Open-the-app-to-check-a-task is friction, and friction is churn. The product needed to be present in the moments when a chore is actually noticed — passing the kitchen, glancing at a wrist, unlocking a phone.

What I built

  • Home-screen widgets on both iOS and Android — small, medium and large, with tap-to-complete and an empty state that rewards a finished day instead of showing a blank box.
  • A native Apple Watch app — Today / All Tasks / Completed as a glanceable list, with task creation on the wrist.
  • Lock-screen widgets so the next chore is visible before the phone is even unlocked.
  • Advanced Flutter animations in the main app, with the widget and watch layers written natively — part Flutter, part native, one product.

Widgets turn a to-do app from a destination into an ambient presence. That is a retention feature disguised as a UI feature.

Why it matters to you

Most Flutter developers stop at the app. Widgets, watch apps and live activities require dropping into Swift/SwiftUI and Kotlin, and knowing where the platform boundary should sit. That boundary is where retention lives — and it is exactly the work I have shipped repeatedly.

Shipping one Flutter codebase to six platforms

ROLE · Software Engineer & Team Lead COMPANY · Sarafan LLC PLATFORMS · 6 + watchOS

The problem

Leading development at Sarafan, the mandate was not "make an Android app." It was: the same product, consistent behaviour, on iOS, Android, Web, Windows, macOS and Linux — plus the Apple Watch — without maintaining six separate codebases or six separate teams.

How it held together

  • Clean architecture with a hard layer boundary — presentation (Cubit/BLoC with immutable freezed state), domain (entities, use cases, contracts), data (repositories, API clients). Platform specifics never leak upward.
  • CI/CD on Codemagic, Bitrise and Xcode Cloud — automated builds and releases, with dev and prod flavors pointed at separate servers so testing never touched production data.
  • Firebase Remote Config as the release valve — version gates and force-update prompts, so a bad build could be contained without waiting for store review.
  • Firebase across the stack — Auth, Firestore, Realtime Database, Crashlytics, Messaging, Analytics — with offline mode and live chat built on top.
  • Growth wired in, not bolted on — AppsFlyer and AppMetrica for deferred deep links and attribution, so marketing had real data from day one.

Cross-platform is not a framework choice, it is an architecture discipline. Flutter makes it possible; layered code and automated pipelines make it survivable.

Why it matters to you

If you need desktop and mobile, or a watch companion, or a codebase your future team can grow into rather than rewrite — that is the same problem, and I have led it end to end.

Let’s work together.

If any of these stories sounds like the problem in front of you, the fastest next step is a conversation. No pitch deck — just tell me about your users.