Реализация отправки изображений в чате мобильного приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация отправки изображений в чате мобильного приложения
Средний
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация отправки изображений в чате мобильного приложения

Пользователь нажимает на скрепку, выбирает фото из галереи — и ждёт. Если за это время ничего не произошло, он нажимает ещё раз. Классический сценарий, когда загрузка изображения реализована без очереди и прогресс-индикатора. Дальше — дубли в чате, крэш на slow network, отзыв в 1 звезду.

Что идёт не так при наивной реализации

Самая частая ошибка — загружать оригинал напрямую. На современных смартфонах фото из камеры весит 4–12 МБ. Отправить такое в чат через multipart/form-data без предварительного сжатия означает: долгое ожидание, зависание UI на main thread (если сжатие вынесено туда же), и дублирование при повторной отправке после таймаута.

На iOS типичная реализация через PHPickerViewController (iOS 14+) отдаёт NSItemProvider, из которого нужно асинхронно получить UIImage. Если сделать это синхронно в completion handler и сразу вызвать ImageIO для ресайза — интерфейс подвиснет на ~300 мс на iPhone 12, и ещё дольше на SE 2nd gen. Правильный путь: получить данные в фоне через loadObject(ofClass:), затем пробросить в DispatchQueue.global(qos: .userInitiated) для сжатия через vImage или UIGraphicsImageRenderer с target size под экран получателя.

На Android аналогичная проблема с ActivityResultContracts.GetContent(): если декодировать Bitmap на главном потоке через BitmapFactory.decodeStream() без inSampleSizeOutOfMemoryError на устройствах с 2 ГБ RAM при выборе нескольких фото подряд.

Как выстроить надёжный pipeline

Полная цепочка выглядит так: выбор → валидация → сжатие → upload с прогрессом → сохранение ссылки → отображение thumbnail.

Выбор и валидация. На iOS — PHPickerViewController с filter: .images, лимит выбора через selectionLimit. Проверяем MIME-тип через UTType до загрузки данных. На Android — PhotoPicker API (Android 13+) или Intent(Intent.ACTION_PICK) для более старых версий; проверка через ContentResolver.getType().

Сжатие. Цель — не более 1 МБ для превью в чате. На iOS: UIGraphicsImageRenderer с target size 1280×1280, jpegData(compressionQuality: 0.75). На Android: Bitmap.createScaledBitmap() + compress(Bitmap.CompressFormat.JPEG, 80, outputStream). В Flutter используем flutter_image_compress — он вызывает нативный кодек, поэтому не блокирует Dart isolate.

Upload. Многочастная загрузка через URLSession.uploadTask(with:from:) на iOS с делегатом urlSession(_:task:didSendBodyData:) для прогресса. На Android — OkHttp с RequestBody.create() и кастомным CountingRequestBody. В React Native удобнее axios с onUploadProgress, но нужно помнить: прогресс-событие срабатывает на JS-потоке, обновление state надо дебаунсировать.

Оптимистичный UI. Показываем thumbnail сразу после выбора, статус "загружается" — пока идёт upload. Если запрос упал — не удаляем сообщение, а показываем кнопку retry. Для этого у каждого сообщения должен быть локальный localId и статус (pending / sent / failed).

Полноэкранный просмотр. На iOS — UIScrollView + UIImageView с pinch-to-zoom через UIPinchGestureRecognizer. Ленивая загрузка оригинала при открытии через SDWebImage или Kingfisher. На Android — PhotoView library или ZoomableImageView из coil + accompanist.

Хранение и CDN

Изображения не хранятся в базе данных. Загружаем в S3-совместимое хранилище (AWS S3, Cloudflare R2, MinIO), в чат пишем только URL. Для превью генерируем thumbnail на стороне сервера через Lambda/Cloud Function при загрузке — это избавляет клиент от повторного сжатия при отображении списка сообщений.

Подписанные URL (presigned URL) с TTL 1–24 часа — обязательно, если чат приватный. На клиенте кэшируем через NSCache (iOS) или DiskLruCache (Android).

Процесс и сроки

Базовая реализация (выбор, сжатие, upload, thumbnail, полноэкранный просмотр) — 2–3 дня при готовом бэкенде. Если нужен мультивыбор (до 10 фото), очередь загрузки с паузой/возобновлением и поддержка GIF — ещё 1–2 дня. Стоимость рассчитывается индивидуально после анализа требований.