
AirbaFresh
Production grocery delivery app with full catalog, checkout, and order lifecycle.
Quick facts
• Role: Lead iOS Developer (led v1 build)
• Timeframe: V1 delivery + early iterations
• Platform: iOS
• Status: Shipped
• Team: iOS lead within a product team
Summary
Airba Fresh is a grocery delivery app focused on fast browsing, search, and checkout driven by delivery address and the nearest warehouse. I led the iOS development of the first version, setting up the architecture, core flows, and delivery-ready feature set.
Key highlights:
• Built v1 end-to-end: auth, address, catalog, cart/workflow, and profile
• Clean layered architecture with MVVM + RxSwift and Moya networking
• Strong workflow/session handling across the app via shared headers and events
Problem
• Grocery UX is state-heavy: address, warehouse availability, promotions, cart, and delivery slots must stay consistent.
• Catalog needed scalable filtering, search, product availability states, and fast product detail loading.
• App had to support both guest browsing and gated actions (addresses, favorites, ordering) without confusing users.
Solution
I implemented a tab-based shopping flow with address-first delivery context, a category catalog with search and filters, and a workflow-driven cart/session that stays consistent across screens. The app supports guest browsing, then escalates to auth only when needed.
• Address selection drives assortment, delivery eligibility, and order readiness
Architecture
• Layered structure: Data (DTO/API/Storage) → Domain (services/repos) → Presentation (MVVM) → Application (factories/coordinator)
• Networking via Moya targets with a single base URL and unified target conventions
• Workflow/session propagated to all requests through a custom Moya plugin header
• Reactive state with RxSwift/RxCocoa (PublishRelay) across services and view models
• App-wide events via EventManager (unauthorized, data refresh, limit events)
• DTO → Entity → UI mapping for catalog, sections, and product details
• Shared workflow repository emits cart count and session changes to update UI globally
• Address CRUD + suggestions/geocoding integrated via a dedicated service layer
Hard problems solved
• Made workflow/cart a first-class shared state and ensured every request carried the right context without leaking it into feature code
• Designed a reactive update model so catalog, product detail, and cart screens stay consistent after mutations (add/remove/qty)
• Built clean boundaries between “nomenclature” (catalog) and workflow/cart to avoid circular dependencies
• Handled auth/unauthorized events globally and safely reset session, repositories, and workflow without stale UI
• Implemented address gating rules (guest vs authorized paths) while keeping navigation predictable
• Ensured search/filter flows degrade cleanly (empty states, clear filter confirmation, out-of-stock states)
Impact / Results
• Delivered the first production version of the iOS app as the iOS lead
• Established a maintainable architecture that supported multiple feature areas and ongoing iteration
• Shipped a stable shopping flow across address, catalog, cart, promotions, and profile
Tech stack
• iOS: Swift, UIKit, RxSwift/RxCocoa
• Architecture: MVVM, Coordinator, layered Data/Domain/Presentation, event bus
• Backend/Infra: REST API (Moya targets), Yandex geocoding/suggest integration
• Tooling: CocoaPods, SnapKit, Kingfisher, Husky (pre-commit), SwiftFormat, xUnique


