Разработка мобильного приложения для доски объявлений (Classifieds)
Доска объявлений — высококонкурентная ниша. Avito, OLX, Kufar задали планку UX и скорости. Пользователь уйдёт, если публикация объявления занимает больше 2-3 минут, а фотографии грузятся по одной. Технически ключевые вещи здесь — быстрый поиск, поиск по карте, мессенджер внутри приложения и надёжная загрузка фото.
Публикация объявления: минимум трения
Форма объявления — категория → заполнение полей → фото → цена → публикация. Поля зависят от категории (для авто — VIN, пробег, год; для недвижимости — площадь, этаж, тип сделки). Динамическая форма: при смене категории поля перерисовываются. JSON Schema от сервера → генерация формы на клиенте (избавляет от хардкода полей в коде).
Загрузка фото — самое узкое место. Пользователь хочет загрузить 10 фото. Последовательная загрузка — слишком долго. Параллельная — перегружает сеть на мобильном. Оптимально: 3 параллельных upload через URLSession background session (iOS) или WorkManager с ListenableFuture (Android). Прогресс-бар для каждого фото индивидуально.
Компрессия перед загрузкой: UIImage.jpegData(compressionQuality: 0.8) или Bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream). Фото с камеры iPhone 15 Pro — 8-15 MB в RAW. После компрессии — 1-2 MB. Для объявления достаточно, трафик экономится.
Определение геолокации объявления
Местоположение объявления — либо текущие координаты, либо выбор на карте, либо ввод адреса с геокодингом. Для продажи вещей обычно достаточно района/города без точного адреса — это важно для безопасности продавца. Точные координаты нужны для недвижимости и авто.
Поиск и фильтрация
Полнотекстовый поиск — Elasticsearch или Typesense на бэкенде. Клиент отправляет запрос, дебаунс 300 мс на поле ввода. Поиск с учётом морфологии (русский язык — «машина» находит «машины», «машиной») — через Elasticsearch с russian analyzer или Typesense с Russian stemmer.
Фильтры цены — range slider. RangeSlider в Material 3 (Android) / кастомный GeometryReader-based range slider (SwiftUI или библиотека RangeSeekSlider). Значения debounce перед запросом.
Поиск по карте — пользователь двигает карту, объявления обновляются по видимой области. onCameraIdle (Google Maps) / onMapIdle (Mapbox) → запрос с bbox текущего viewport. Маркеры на карте, tap — карточка объявления.
Для недвижимости важна кластеризация: в одном доме 50 объявлений. Кластер показывает количество, при zoom-in раскрывается в отдельные маркеры или список.
Мессенджер
Чат продавца и покупателя внутри приложения — без обмена номерами телефона. Firebase Realtime Database или Supabase Realtime — быстрый способ запустить чат с real-time сообщениями. Для серьёзного масштаба — собственный WebSocket-сервер или Stream Chat SDK.
Структура сообщений: { id, conversation_id, sender_id, text, image_url, timestamp, read_at }. read_at для статуса прочтения. Push-уведомление при новом сообщении — FCM/APNs data push с conversation_id в payload для deep link в конкретный чат.
Фото в чате — пользователь отправляет фото. Сжатие до 800-1200px, upload в S3/Cloudflare R2, сообщение содержит URL. При отображении — lazy loading с progressive placeholder.
Антиспам: ограничение скорости сообщений (rate limiting на сервере), блокировка пользователя.
Модерация объявлений
На стороне клиента: предупреждение при вводе телефона/почты в тексте объявления (обход контактов через платформу). Кнопка «Пожаловаться» на каждом объявлении — попап с причиной жалобы, отправка на сервер.
Автоматическая модерация фото: Google Cloud Vision API SafeSearch — проверка на explicit контент. Интегрируется в upload pipeline на сервере, клиент просто получает статус объявления (pending_moderation / approved / rejected).
Монетизация и продвижение
«Поднять объявление», «VIP-статус», «выделить» — классические платные опции. In-app purchase через StoreKit 2 / Google Play Billing или одноразовая оплата через Stripe.
Push-кампании: уведомление владельцу при добавлении в избранное, при снижении цены на избранное объявление другого пользователя.
Стек: Flutter (скорость разработки важна для marketplace), Elasticsearch/Typesense для поиска, Firebase/Supabase или custom WebSocket для чата, Cloudflare R2 / S3 для медиа, Google Maps SDK / Mapbox для карты.
Этапы: структура категорий и схема данных → публикация → поиск и фильтрация → карта → чат → модерация → монетизация → тестирование → публикация.
Срок: от 14 до 24 недель. Стоимость рассчитывается индивидуально.







