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

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація AI-перевірки граматики та стилю тексту у мобільному додатку
Середній
~3-5 днів
Часті запитання

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

Етапи розробки

Останні роботи

  • 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-перевірки граматики та стилю тексту в мобільному додатку

Вбудована перевірка орфографії iOS та Android ловить опечатки, але не розуміє контекст. «Я пошов у банк» — орфографічно правильно. «Звіт був мною написаний» — технічно вірно, але стилістично слабо для ділового документа. Ось тут потрібен AI.

Нативні засоби як перший шар

Перш ніж тягнути LLM, використовуємо те, що вже є у платформі.

На iOS NLLanguageRecognizer + UITextChecker закривають базову орфографію. NLTagger з .lemma та .lexicalClass дозволяє будувати прості стилістичні правила — наприклад, флагити пасивний залог через паттерни лем.

func checkPassiveVoice(in text: String) -> [NSRange] {
    let tagger = NLTagger(tagSchemes: [.lexicalClass, .lemma])
    tagger.string = text
    var findings = [NSRange]()

    tagger.enumerateTags(in: text.startIndex..<text.endIndex,
                         unit: .word,
                         scheme: .lexicalClass) { tag, range in
        // Спрощений паттерн: форма "бути" + дієприкметник
        if tag == .verb {
            let lemma = tagger.tag(at: range.lowerBound, unit: .word, scheme: .lemma).0
            if lemma?.rawValue == "be" {
                findings.append(NSRange(range, in: text))
            }
        }
        return true
    }
    return findings
}

Для кириличних мов паттерн складніше — потрібен аналіз морфології. NLTagger з кириличними мовами працює з iOS 16+, точність достатня для базової перевірки.

AI-рівень: коли нативного мало

LanguageTool API закриває граматику для 20+ мов, повертає конкретні правила та пропозиції щодо виправлення. Self-hosted версія на Java — для приватних даних. Вартість cloud API розумна для B2B-продуктів.

// Android - запрос до LanguageTool
data class LTRequest(
    val text: String,
    val language: String,  // "en-US", "de-DE"
    val enabledOnly: Boolean = false
)

suspend fun checkGrammar(text: String, lang: String): List<GrammarMatch> {
    val response = languageToolApi.check(LTRequest(text, lang))
    return response.matches.map { match ->
        GrammarMatch(
            range = match.offset..(match.offset + match.length),
            message = match.message,
            rule = match.rule.id,
            replacements = match.replacements.take(3).map { it.value }
        )
    }
}

LanguageTool повертає rule.id — наприклад, MORFOLOGIK_RULE_EN_US для орфографії або PASSIVE_VOICE для стилю. Це дозволяє фільтрувати по типу: користувач може відключити стилістичні попередження, залишити тільки граматику.

Підсвітлення помилок у тексту

Знайдені помилки потрібно підкреслити прямо у полі введення. На iOS — NSAttributedString з .underlineStyle та .underlineColor. Червоний для граматики, жовтий для стилю — стандартна конвенція.

func applyUnderlines(_ matches: [GrammarMatch], to textStorage: NSTextStorage) {
    // Спочатку знімаємо старі підкреслення
    let fullRange = NSRange(location: 0, length: textStorage.length)
    textStorage.removeAttribute(.underlineStyle, range: fullRange)

    textStorage.beginEditing()
    for match in matches {
        let color: UIColor = match.isGrammar ? .systemRed : .systemOrange
        textStorage.addAttributes([
            .underlineStyle: NSUnderlineStyle.single.rawValue,
            .underlineColor: color
        ], range: match.nsRange)
    }
    textStorage.endEditing()
}

На Android — SpannableStringBuilder з UnderlineSpan або кастомний ForegroundColorSpan + UnderlineSpan. Jetpack Compose поки не має нативного способу підкреслювати частини TextField — потрібен BasicTextField з кастомним visualTransformation.

Дебаунс та батчинг

Перевірка запускається не на кожне натиснення клавіші. Оптимальна схема:

  • Дебаунс 800–1200 мс після останньої зміни
  • Перевіряємо тільки змінений параграф, не весь текст
  • Кешуємо результати по хешу параграфа — якщо користувач повернув текст до оригіналу, перепровірка не потрібна
private var checkWorkItem: DispatchWorkItem?
private var paragraphCache = [String: [GrammarMatch]]()

func scheduleCheck(for paragraph: String) {
    checkWorkItem?.cancel()
    let hash = paragraph.hashValue.description

    if let cached = paragraphCache[hash] {
        applyMatches(cached)
        return
    }

    checkWorkItem = DispatchWorkItem { [weak self] in
        Task {
            let matches = try await self?.grammarService.check(paragraph)
            await MainActor.run {
                self?.paragraphCache[hash] = matches ?? []
                self?.applyMatches(matches ?? [])
            }
        }
    }
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: checkWorkItem!)
}

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

Інтеграція LanguageTool з підсвітленням — 4–7 днів. Повноцінна реалізація з дебаунсом, кешем, настройками рівня перевірки та підтримкою кількох мов — 2–3 тижні.