top of page
Banner Apps.jpg

KEX

Multi-brand food delivery app rebuilt mid-project to achieve production quality and stability.

Quick facts

• Role: Lead iOS Developer
• Timeframe: Mid-development takeover → refactor → release
• Platform: iOS app + Django backend
• Status: Released, then discontinued (business moved to 3rd-party delivery apps)
• Team: 3 iOS devs (after takeover)

Summary

KEX is a multi-brand food delivery app where brand availability and menu assortment depend on the selected delivery address. I joined mid-project to take over from a single developer producing low-quality code. My team and I rewrote large parts of the app to raise reliability and maintainability, which delayed delivery but made the codebase sustainable.
Key highlights:
• Major iOS refactor: storyboard-heavy UI → programmatic UIKit + SnapKit
• Networking refactor: ad-hoc Alamofire layer → Moya-based services with plugins
• Consistent MVVM + Repository + Coordinator architecture across features

Problem

• Existing codebase was unstable and hard to extend. Features were being added faster than quality.
• Core flows are state-heavy: address → brand selection → menu → modifiers → cart → payment → orders.
• Integrations had strict constraints: 3DS payments, push routing, geocoding, and localization.

Solution

We rebuilt the iOS client around a modular, reactive architecture with clear boundaries: services and repositories for domain orchestration, MVVM for presentation, and coordinators for navigation. We also standardized networking, localization, assets, and dependency injection so new features could be added without compounding tech debt.
• Prioritized correctness and long-term maintenance over short-term speed

Architecture

• MVVM + Repository pattern with Coordinators for feature flows and routing
• Programmatic UIKit + SnapKit; reusable components for menu, cart, modifiers, and states
• RxSwift/RxCocoa for state and side effects (relays, Singles, typed outputs)
• Moya target/services split by domain (auth, menu, orders, payments, profile, docs, support)
• Networking plugins injecting auth, locale, headers, and dynamic URL context (lead UUID)
• Local storage split by responsibility: tokens, flags, cached domain objects, payment state
• Backend “pipeline” layer with audited service calls and scheduled sync tasks (iiko, CloudPayments, FCM)

Hard problems solved

• Executed a mid-flight takeover: stabilized delivery by refactoring most of the codebase without breaking critical flows
• Rebuilt networking into typed Moya services with consistent error mapping, retries, and auth renewal handling
• Implemented address→lead/brand context propagation so all downstream menu/cart requests stayed coherent
• Integrated 3DS payment flows end-to-end (iOS web view controller + backend confirmation pipeline)
• Built modifier-heavy cart item modeling (required counts, max additions, per-item comments) with deterministic UI summaries
• Standardized localization/assets/DI to stop regressions and reduce merge conflicts across a growing team
• Implemented push routing based on payload types (promo, rating, order status) without scattering deep link logic

Impact / Results

• Shipped a maintainable v1 after a major refactor and architecture reset
• Improved stability and developer velocity by removing storyboard sprawl and inconsistent networking
• Project was later discontinued for business reasons, not technical blockers

Tech stack

• iOS: Swift, UIKit, SnapKit, RxSwift/RxCocoa, Moya, StoreKit/Apple Pay, Lottie, Yandex MapKit
• Architecture: MVVM, Repository, Coordinator, DI, plugin-based networking
• Backend/Infra: Django, PostgreSQL, Redis, RabbitMQ/Celery, Firebase Cloud Messaging, IIKO, CloudPayments (3DS), NGINX
• Tooling: CocoaPods, swiftformat, xunique, Swagger (drf-yasg), Docker

bottom of page