iOS app + real-time tracking + geo-feed
Artifact
Case Study
Full-cycle mobile platform connecting home chefs with local food lovers: native iOS app (Swift/SwiftUI) with dual-role architecture (Chef & Customer), real-time order tracking with map integration, multi-step registration with OTP verification, geo-filtered food feed with recommendations, cart & checkout with pickup/delivery options, MIR card payment processing, kitchen quality verification via photo/video, push notifications, and a Node.js/PostgreSQL backend with geospatial queries, WebSocket order updates, and S3 media pipeline.
40+
UI screens designed
2 (Chef + Customer)
User roles
4
Registration steps
A Moscow-based client wanted to launch a peer-to-peer food marketplace — a platform where home chefs could sell their dishes to neighbors, with real-time delivery tracking, quality verification, and payment processing. Existing food delivery apps (Yandex.Eda, Delivery Club) cater to restaurants, not individuals. The client needed a two-sided marketplace with distinct experiences for chefs (menu management, order processing, kitchen verification) and customers (geo-based discovery, cart, checkout with pickup/delivery, order tracking on map). The platform had to handle geospatial search (find chefs within 50–1000m radius), OTP-based dual verification (phone + email), MIR payment card processing, real-time order status updates via WebSocket, photo/video kitchen verification for food safety compliance, and map-based delivery routing with ETA calculation. Per client agreement, the app name and logo shown are changed from the original.
Designed and built a full-stack two-sided food marketplace across iOS and backend.
dual-role onboarding — at registration Step 1, user chooses Chef or Customer, defining their entire navigation tree; 4-step registration flow (role selection → personal data with bio/DOB/gender → contact info with phone/email/address with geolocation → dual OTP verification for both phone and email); personalized geo-filtered food feed with recommendation carousel (featured dish with chef avatar, rating, price, one-tap add to cart), search with advanced filters (distance radius chips 50–1000m, price range slider, sort order, food type tags — Meat, Salad, Appetizer, Pastry, Side, Soup, Drinks, Grill); dish detail screen with full-bleed hero photo, chef badge, rating with review count, description, ingredients, category tags, and 'More from this chef' section; cart with item management (quantity +/−, favorites, delete), line-item breakdown and total; checkout with segmented control for Pickup vs Delivery (pickup shows chef address + map link, delivery shows user address + delivery fee calculation), saved MIR payment cards with add/remove, order summary with service fee breakdown; 6-stage order tracking on live map (Pending → Accepted → Cooking → In Transit → Delivered → Completed) with real-time driver position via WebSocket, route rendering with ETA (e.g. '32 min, 27.6 km'), and order detail overlay; payment error screen with retry flow and support contact; push notification center with order status updates and payment failure alerts.
profile with rating, bio, menu management, 'Add dish' form (photo upload, name, description, ingredients, tags, price), order management (incoming orders with Accept/Reject, order detail with item list and 'Start cooking' action), kitchen quality verification (photo of kitchen/products for sanitary inspection + live camera stream), media gallery (uploaded photos + video for transparency).
geospatial queries via PostGIS (ST_DWithin for radius search, ST_Distance for distance calculation, spatial index on chef locations for sub-50ms query time at 100K+ records), WebSocket server (Socket.IO) for real-time order status push and delivery driver location updates, S3 media pipeline (dish photos, chef avatars, kitchen verification photos/videos — upload via pre-signed URLs, Sharp-based image resizing to 3 breakpoints, CloudFront CDN for delivery), MIR payment gateway integration (tokenized card storage, 3-D Secure, idempotent charge requests), OTP service (SMS via SMS.RU provider + email via Nodemailer/SES, 6-digit codes with 90-second TTL and rate limiting), order state machine (Pending → Accepted → Cooking → Ready → InTransit → Delivered, with compensating transitions for cancellation/refund), recommendation engine (collaborative filtering based on order history + geo-proximity scoring), and structured logging via Pino with request tracing.
Step-by-step walkthrough of the product interface
Onboarding — 'Order delicious food from neighbors' welcome screen with LocalFood branding
Login — email/phone + password authentication with 'Sign up' link
OTP — phone number verification with 6-digit code entry and 1:27 resend timer
OTP — email verification with 6-digit code sent to example@mail.ru
Registration Step 1 — role selection: Chef (with chef hat icon) or Customer (with utensils icon)
Registration Step 2 — personal data: first name, last name, about me bio, date of birth, gender
Registration Step 3 — contact info: phone or email, address with geolocation pin, password
Registration Step 4 — email OTP verification during registration flow
Registration Step 4 — phone OTP verification during registration flow
Main feed — delivery address, recommendation carousel (Caesar Salad 249₽), search, chef cards with ratings
Feed with cart badge — floating cart button showing 2184₽ / 2 items
Feed with active order banner — Order #160924 'Awaiting pickup' with 'On map' button
Filters — distance chips (50–1000m), price range slider (120–1100₽), sort by price, food type tags
Dish detail — full photo, chef badge (4.8★), 141 reviews, description, ingredients, tags, 'More from chef'
Dish detail (alternate) — same layout with different dish, showing add-to-cart 249₽ button
Chef profile — avatar, username, 4.8★ rating, 'About me' bio, menu list with prices and add buttons
Cart — items with photos, prices, quantity controls (−/+), favorites, delete, 2 items total 596₽
Checkout (Pickup) — pickup/delivery toggle, chef address on map, MIR cards, 2 items 596₽ + 49₽ service = 645₽
Checkout (Delivery) — delivery selected, user address, MIR cards, 596₽ + 49₽ service + 120₽ delivery = 765₽
Payment error — red screen 'Order #52120120 payment failed' with Retry button and support contact
Order tracking — map with route, 'Awaiting pickup' status, 32 min ETA, 27.6 km, order details overlay
Order tracking — 'In transit' status with live driver position on map route
Order tracking — chef view: 'Deliver the dish to the customer' instruction with map
Order delivered — status 'Delivered', items list with 'Repeat order' button
Account menu — Profile, Addresses, Notifications, Settings + 'Become a chef' CTA, Logout/Support
Payment data — saved MIR cards (····7289, ····3212) with delete/confirm actions, 'Add card' button
Add payment method — card number, name, MM/YY, CVV fields with 'Add' button
Notifications — 'Your order is ready' (×2), 'Payment failed' alerts with order numbers and timestamps
Address list — saved delivery address (Moscow, pl. Lenina 11) with edit icon, 'New address' button
Address map — full map view with route (32 min / 27.6 km), delivery address input, apartment/floor fields, 'Detect location'
Profile edit — avatar upload, name, surname, username, bio, DOB, gender, email/phone, password
Chef profile (own view) — avatar, name, rating 4.8★, 'Edit' button, 'My orders' badge, bio, menu with 'Add dish'
Chef orders — incoming order #160924 (1265₽, 'Delivered') with food thumbnails, Accept/Reject buttons
Chef order detail — Order #160924 'Accepted', item list (Caesar ×2, beef, crab salad) with 'Start cooking' button
Kitchen verification — 'Photograph kitchen and products for quality and sanitary assessment' with photo/upload buttons
Camera stream — 'Prepare camera, products and start broadcast' with camera preview window
Media gallery — uploaded photos grid + video section with play button, 'Order ready' action
Dish (chef view) — same detail screen but with delete icon and 'Edit' button instead of add-to-cart
Edit dish — photo upload area, name field, description, ingredients, tags, price, 'Save' button
Create dish — empty form with photo placeholder, name, description, ingredients fields, 'Save' button
Documents and deliverables from the project
iOS app + real-time tracking + geo-feed
Artifact
Verification report
Release gate
8-phase checklist before release
Delivered a production-ready two-sided food marketplace: 40+ iOS screens covering the complete user journey from onboarding to order delivery, dual-role architecture (Chef manages menu/orders/verification, Customer discovers/orders/tracks), real-time map tracking with WebSocket-driven status updates and ETA, PostGIS-powered geospatial discovery (sub-50ms on 100K+ chef records), MIR payment processing with 3-D Secure, kitchen quality verification via photo and live video stream. The platform handles the full order lifecycle with 6 tracked statuses, push notifications at every transition, and error handling with retry flows. Per client agreement, the app was delivered under a pseudonym (LocalFood) with a neutral logo — the actual product operates under the client's brand in Moscow.
Chef and Customer share authentication and core infrastructure but have entirely different navigation trees, screens, and data flows. Role is selected at registration Step 1 and defines the app's behavior: Customers see a geo-feed, cart, checkout, and tracking; Chefs see menu management, order queue, kitchen verification, and a chef-specific profile. Implemented via SwiftUI's NavigationView with role-conditional root views, @EnvironmentObject for role state propagation, and a shared data layer (CoreData for offline cache + URLSession API sync). Choosing SwiftUI over UIKit in 2021 was a deliberate forward-thinking decision — the framework was mature enough on iOS 14+ for this scope, while giving us declarative UI composition and significantly faster iteration cycles.
Food discovery is driven by proximity — users see dishes from chefs within a configurable radius (50m to 1000m). Implemented via PostGIS: chef locations stored as geography(POINT, 4326), spatial GIST index, and ST_DWithin for radius filtering. Distance chips in the filter UI map directly to SQL parameters. At 100K+ chef records, queries return in under 50ms. Combined with collaborative filtering (order history + proximity score) for the recommendation carousel.
Order lifecycle: Pending → Accepted → Cooking → Ready/InTransit → Delivered → Completed. Each transition triggers a WebSocket event (via Socket.IO) that updates the customer's map view in real-time: driver location pin animates along the route, ETA recalculates, and the status banner changes. MapKit renders the route polyline with distance and time overlay ('32 min, 27.6 km'). Compensating transitions handle cancellation (refund via MIR gateway) and payment failure (retry screen with support contact). Chef receives push notification on new order and can Accept/Reject from the notification or the orders screen.
Before a chef can start receiving orders, they must pass kitchen verification: upload photos of their kitchen and products (reviewed by the platform's moderation team), and optionally start a live camera stream for real-time inspection. The verification flow uses the device camera (AVFoundation) for photo capture and HLS for live streaming to a moderation dashboard. Media is uploaded to S3 via pre-signed URLs, resized via Sharp, and served via CloudFront. This feature was a regulatory requirement from the client to demonstrate food safety diligence.
Have a similar project? Get an estimate or book a call.
Full product flow: registration, public offer acceptance with audit trail, PDF proof with seal/signature, admin panel. Legally compliant, mobile‑first.
Full-cycle restaurant management system: role-based access (Chef, Employee, Accountant, Owner), ingredient inventory with cost tracking, roll recipes with auto-calculated cost/margin, set composition with pricing, order management, supply/write-off logging, accounting with Excel export, analytics dashboards, and a full audit trail for every change.
Full‑cycle mobile crypto wallet for iOS: non‑custodial key management with AES‑256‑GCM encryption, 4‑digit PIN + Face ID biometric auth, 3‑step onboarding with value‑driven storytelling, multi‑asset portfolio dashboard with real‑time price feeds (BTC, ETH, LTC, XRP), built‑in exchange with interactive candlestick charts and Buy/Sell flow, spending analytics with category‑segmented donut chart, QR‑code scanner for instant P2P transfers, multi‑currency fiat settings with 6+ currencies, OAuth social login (Google, Apple ID), 4‑digit OTP email verification, and a Node.js/PostgreSQL backend with WebSocket price streaming and CoinGecko aggregation.