Реалізація AI-рерайтингу тексту у мобільному додатку

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

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація AI-рерайтингу тексту у мобільному додатку
Простий
~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

Реалізація AI-рерайтингу тексту в мобільному додатку

Рерайтинг у мобільному додатку — вузька задача: користувач виділив фрагмент, натиснув кнопку, отримав переписану версію. Проста ідея, але реалізацій-граблей тут більше, ніж здається.

Робота з виділенням тексту

Найтрудніше — не AI-частина, а коректна робота з selectedRange при заміні тексту. Якщо замінити NSRange неправильно, курсор стрибає на початок, виділення злітає, історія undo ломиться.

// iOS: безопасна заміна виділеного тексту зі збереженням undo
func replaceSelection(with newText: String) {
    guard let textView = self.textView,
          let selectedRange = Range(textView.selectedRange, in: textView.text) else { return }

    // Реєструємо undo перед змінами
    textView.undoManager?.registerUndo(withTarget: self) { [oldText = textView.text, oldRange = textView.selectedRange] target in
        target.restoreText(oldText, cursorAt: oldRange)
    }

    textView.textStorage.beginEditing()
    textView.textStorage.replaceCharacters(
        in: textView.selectedRange,
        with: NSAttributedString(string: newText, attributes: textView.typingAttributes)
    )
    textView.textStorage.endEditing()

    // Установлюємо курсор у кінець вставленого тексту
    let newCursorPos = textView.selectedRange.location + newText.utf16.count
    textView.selectedRange = NSRange(location: newCursorPos, length: 0)
}

На Android з EditText аналог через Editable.replace() + Selection.setSelection(). У Compose — через TextFieldState у новому API (доступний з Compose BOM 2024.06).

Промпти для різних сценаріїв рерайтингу

Універсального промпту немає. У кожного режиму свій:

enum RewriteMode {
    case simplify, formalize, casual, shorten, expand, fix

    var systemPrompt: String {
        switch self {
        case .simplify:
            return "Rewrite the text using simpler words and shorter sentences. Preserve all meaning. Same language as input."
        case .formalize:
            return "Rewrite in formal business style. Remove colloquialisms. Preserve all key information."
        case .casual:
            return "Rewrite in a friendly, conversational tone. Natural language, not stiff."
        case .shorten:
            return "Shorten by 40-60%. Keep only essential information. No filler."
        case .expand:
            return "Expand with relevant details and examples. Add 50-100% more content. Stay on topic."
        case .fix:
            return "Fix grammar, spelling, and awkward phrasing. Minimal changes to preserve the original voice."
        }
    }
}

Ключова рядок у всіх промптах: «Same language as input». Без неї GPT іноді перемикається на англійську, особливо якщо у тексту є технічні терміни.

UI паттерн: «до/після»

Користувач повинен бачити оригінал поряд з рерайтом та легко відкатитися. Не сховуйте джерело.

@Composable
fun RewriteResultView(
    original: String,
    rewritten: String,
    onAccept: () -> Unit,
    onDiscard: () -> Unit,
    onRetry: () -> Unit
) {
    Column(modifier = Modifier.fillMaxWidth()) {
        Text("Оригінал", style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
        Text(
            text = original,
            modifier = Modifier
                .fillMaxWidth()
                .background(MaterialTheme.colorScheme.surfaceVariant, RoundedCornerShape(8.dp))
                .padding(12.dp),
            style = MaterialTheme.typography.bodyMedium.copy(
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        )

        Spacer(Modifier.height(8.dp))

        Text("Результат", style = MaterialTheme.typography.labelSmall)
        Text(
            text = rewritten,
            modifier = Modifier
                .fillMaxWidth()
                .background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(8.dp))
                .padding(12.dp)
        )

        Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
            TextButton(onClick = onDiscard) { Text("Скасувати") }
            TextButton(onClick = onRetry) { Text("Ще варіант") }
            Button(onClick = onAccept) { Text("Прийняти") }
        }
    }
}

Кнопка «Ще варіант» важлива — перший рерайт не завжди підходить, але возитися з промптом користувач не хоче.

Diff-підсвітлення змін

Для режиму fix (правка граматики) корисно показати, що саме змінилося. Простий diff на клієнті без сервера:

// Спрощений word-level diff
func computeDiff(original: String, rewritten: String) -> [DiffChunk] {
    let origWords = original.split(separator: " ").map(String.init)
    let newWords = rewritten.split(separator: " ").map(String.init)
    // LCS-based diff, реалізація через стандартний алгоритм
    return lcs(origWords, newWords)
}

На Android — DiffUtil з androidx.recyclerview працює для списків, для тексту потрібна власна реалізація LCS або бібліотека java-diff-utils.

Орієнтири за часом

Базовий рерайтинг (один режим, без diff) — 2–4 дні. Повноцінна реалізація з множиною режимів, diff-підсвітленням, коректним undo та історією варіантів — 1.5–2 тижні.