Клієнти часто приходять із задачею real-time перекладу в мобільному додатку — для чату, текстового введення чи документів. Кожен сценарій потребує свого підходу: затримка 200–400 мс для чату, debounce для live-введення, батч з прогреc-баром для документів. За багаторічний досвід ми реалізували понад 30 проєктів з перекладом для медичного туризму, e-commerce та месенджерів. Гарантуємо стабільну роботу та дотримання App Store Review Guidelines. Знижуємо вартість інтеграції за рахунок продуманої архітектури. У цій статті розбираємо стек, архітектуру та практичні прийоми.
Як обрати провайдера перекладу?
Ми сертифіковані розробники Google Cloud і маємо досвід інтеграції всіх трьох основних провайдерів. Порівняння в таблиці:
| Провайдер | Мови | Якість | Офлайн | Ціна |
|---|---|---|---|---|
| Google Cloud Translation v3 | 130+ | NMT, відмінно | Ні | за символи |
| DeepL API | 31 (основні) | Краще для європейських | Ні | за символи, є безкоштовний ліміт 500K/міс |
| ML Kit Translate | 58 | Добре для офлайн | Так | безкоштовно |
Google Cloud Translation — стандарт для продакшену. Підтримує формальні/неформальні регістри, REST та gRPC. DeepL — вибір, коли критично якість перекладу складних текстів (німецька, французька). ML Kit — основа для офлайн-сценаріїв: модель ~15 МБ на мовну пару, завантажується один раз.
Чому важливий debounce?
Головна помилка live-перекладу — надсилати запит на кожне натискання клавіші. При швидкості друку 200 символів/хвилину це 3–4 запити на секунду, з яких 90% підуть у сміття до відповіді. Правильний патерн — debounce зі скасуванням попередніх незавершених запитів.
На iOS (Combine):
@Published var inputText: String = ""
inputText
.publisher
.debounce(for: .milliseconds(500), scheduler: RunLoop.main)
.removeDuplicates()
.filter { $0.count >= 3 }
.flatMap(maxPublishers: .max(1)) { [weak self] text -> AnyPublisher<String, Never> in
guard let self else { return Empty().eraseToAnyPublisher() }
return self.translationService.translate(text)
.replaceError(with: "")
.eraseToAnyPublisher()
}
.receive(on: RunLoop.main)
.assign(to: &$translatedText)
flatMap(maxPublishers: .max(1)) — це switchMap: при новому введенні скасовує попередній запит. Без цього старі відповіді можуть перезаписати актуальний переклад.
На Android (Kotlin Flow):
val translatedText: StateFlow<String> = inputText
.debounce(500)
.filter { it.length >= 3 }
.distinctUntilChanged()
.flatMapLatest { text ->
flow { emit(translationRepo.translate(text)) }
.catch { emit("") }
}
.stateIn(viewModelScope, SharingStarted.Lazily, "")
flatMapLatest — еквівалент switchMap, скасовує попередній coroutine.
Без скасування при швидкому введенні pipeline захлинається: кожен новий символ запускає переклад, але відповіді приходять у довільному порядку. Користувач бачить «мерехтіння» перекладу. Використання flatMapLatest гарантує, що в момент нового введення попередній переклад скасовується, і в UI потрапляє лише останній результат.
Інтеграція з Google Cloud Translation v3
suspend fun translate(text: String, targetLang: String = "ru"): String {
val body = JSONObject().apply {
put("q", text)
put("target", targetLang)
put("format", "text")
}
val response = httpClient.post("https://translation.googleapis.com/language/translate/v2") {
header("Authorization", "Bearer $accessToken")
contentType(ContentType.Application.Json)
setBody(body.toString())
}
return response.body<TranslationResponse>().data.translations[0].translatedText
}
Для access_token у продакшені — сервісний акаунт GCP, JWT-підпис на бекенді. Мобільний клієнт отримує короткостроковий токен через свій /api/translate-token ендпоінт. API-ключ GCP в APK/IPA — ні.
ML Kit для офлайн-сценаріїв
// iOS: Google ML Kit Translate
let options = TranslatorOptions(sourceLanguage: .english, targetLanguage: .russian)
let translator = Translator.translator(options: options)
translator.downloadModelIfNeeded { error in
guard error == nil else { return }
translator.translate("Hello world") { result, error in
print(result ?? "")
}
}
Модель завантажується один раз через Wi-Fi. Далі — робота без мережі. Затримка на пристрої 20–50 мс на фразу. Ідеально для месенджерів, субтитрів в офлайн-відео, туристичних додатків.
Кешування перекладів
Повторні запити одного й того ж тексту — гроші в сміття. Кеш на рівні SQLite (Room/CoreData) з ключем sha256(source_text + target_lang). TTL 7 днів для звичайного контенту, без TTL для статичних рядків UI. На рівні HTTP — Cache-Control для GET-запитів. Згідно з документацією Google Cloud Translation, підтримуються GET-запити з параметрами, що дозволяє кешувати на рівні URLCache / OkHttp Cache. Це суттєво скорочує витрати на API.
| Сценарій | Без кешу | З кешем |
|---|---|---|
| Live-переклад (100 запитів) | 100 API-викликів | ~10–20 викликів (90% влучань) |
| Батч-переклад документів (1000 сторінок) | 1000 викликів | ~200 викликів (80% влучань) |
Приклад з практики
У додатку для медичного туризму (iOS + Android) перекладали описи клінік та відгуки пацієнтів (en→ru, ru→en, de→ru). Cloud-переклад для контенту при завантаженні, ML Kit офлайн для інтерфейсу консультації. Debounce 700 мс для пошукового рядка. Кеш перекладу в Room знизив кількість API-запитів на 73% протягом першого тижня після запуску, а швидкість відображення перекладу зросла на 40%. Економія бюджету на API склала значну суму.
Процес роботи
- Аналітика: вивчаємо сценарії використання (чат, live, батч), вимоги до затримки та мов.
- Проектування: обираємо провайдера, архітектуру (хмарний/офлайн/гібрид), проектуємо debounce та кеш.
- Реалізація: інтеграція через бекенд, написання модуля перекладу, налаштування скасування запитів.
- Тестування: перевіряємо затримки при різних навантаженнях, якість перекладу, роботу в офлайн.
- Деплой: публікація в App Store / Google Play, моніторинг помилок через Crashlytics.
Що входить в роботу
- Вихідний код iOS та/або Android з інтеграцією обраного провайдера.
- Документація з архітектури, ключів доступу та експлуатації.
- Налаштування бекенд-токенів та доступу до API.
- Навчання команди роботі з рішенням.
- Гарантійна підтримка 1 місяць після здачі.
Терміни та вартість
Базова інтеграція одного провайдера з debounce та кешем займає від 5 до 7 днів. Додавання ML Kit офлайн, автовизначення мови та форматованого тексту — від 4 до 6 днів. Точні терміни та вартість розраховуються індивідуально, з урахуванням вашого бюджету. Отримайте консультацію щодо вибору провайдера та архітектури перекладу. Зв'яжіться з нами для оцінки вашого проєкту.







