Разработка публикации постов с текстом в мобильном приложении
Текстовый пост — самый базовый контент в социальных приложениях. Но «просто TextField + кнопка Отправить» работает плохо: пользователь пишет длинный текст, сворачивает приложение, возвращается — черновик потерян. Или набирает текст с плохим интернетом, жмёт «Опубликовать», получает ошибку — и снова тот же пустой экран. Эти детали и отличают нормальную реализацию от быстрой.
Редактор текста и форматирование
Простой вариант
UITextView (iOS) или BasicTextField/OutlinedTextField (Compose) — если форматирование не нужно. Обязательно: autocorrectionType, spellCheckingType, минимальная высота с авторасширением до максимума (5-6 строк). На iOS авторасширение UITextView — через NSLayoutConstraint на высоту с обновлением в textViewDidChange.
С форматированием (жирный, курсив, списки)
UITextView + NSAttributedString — минимальный вариант для iOS. Для полноценного редактора — RichTextKit (open source, Swift) или кастомная реализация на NSTextStorage. На Android — Spannable/SpannableStringBuilder с EditText, или Markwon если нужен preview Markdown.
В Flutter популярен flutter_quill — Delta-формат, поддерживает вставку изображений, списки, заголовки. Но добавляет ~2 МБ к бинарнику и требует сериализации Delta → backend-формат.
Хранить текст на сервере лучше в нейтральном формате — HTML или Markdown — не в Delta и не в NSAttributedString-blob. Клиент конвертирует при загрузке.
Черновики
Черновик — обязателен. Реализация: при каждом изменении текста сохраняем в UserDefaults (iOS) или DataStore (Android) с дебаунсом 1-2 секунды. Ключ — draft_post или draft_post_{channel_id} если черновик привязан к конкретному контексту.
При открытии экрана создания поста: проверяем наличие черновика → если есть, показываем UIAlertController «Продолжить черновик?» или сразу восстанавливаем текст. После публикации или ручного сброса — очищаем.
На Flutter — SharedPreferences или Hive, обновление через debounceTime(Duration(seconds: 1)) в stream.
Публикация с плохим интернетом
Оптимистичное обновление + очередь повторов — стандарт для социалок. При нажатии «Опубликовать»:
- Генерируем локальный
client_post_id(UUID). - Сразу добавляем пост в ленту со статусом
pending(серый/полупрозрачный индикатор). - Отправляем запрос на сервер. При успехе — заменяем
client_post_idна серверныйid, убираем индикатор pending. - При ошибке — показываем статус «Не отправлено» с кнопкой «Повторить».
На Android для retry при восстановлении сети используем WorkManager с NetworkConstraint. На iOS — BGTaskScheduler для background retry или повтор при NWPathMonitor event.
Ограничения и валидация
Лимит символов — отображаем счётчик, не блокируем ввод до лимита (Twitter-подход: показываем -20 красным). На сервере всё равно валидируем — клиентская валидация не защита.
Запрет пустой публикации: кнопка активна только при text.trimmingCharacters(in: .whitespacesAndNewlines).count > 0. На Compose — enabled = text.isNotBlank().
Упоминания и хештеги в тексте — отдельная задача (парсинг @username и #tag с подсветкой). Если нужны — реализуем через NSAttributedString/AnnotatedString с regex-паттернами и отдельными tap-хендлерами.
Этапы работы
Проектирование структуры поста и API → UI редактора с черновиком → логика публикации с оптимистичным обновлением → обработка ошибок и retry → тестирование офлайн-сценариев.
Сроки
Простой текстовый редактор с черновиком и retry — 2-3 дня. С форматированием, упоминаниями, хештегами — 5-7 дней. Стоимость рассчитывается индивидуально.







