Реализация базы знаний в мобильном приложении
База знаний отличается от FAQ масштабом и структурой: не 20 вопросов-ответов, а сотни статей с категоризацией, поиском, версионированием контента и возможностью навигации по теме. Для мобильного приложения это означает другую архитектуру: локальный поиск по индексу, кеширование, offline-доступ и рендеринг разметки.
Источники контента и синхронизация
CMS-бэкенд с API
Наиболее универсальный подход — собственный или headless CMS (Contentful, Strapi, Sanity) с REST/GraphQL API. Мобильный клиент скачивает статьи при первом запуске и при обновлении, хранит в локальной БД.
// Android: Room-схема для статей базы знаний
@Entity(tableName = "kb_articles")
data class KbArticle(
@PrimaryKey val id: String,
val title: String,
val content: String, // Markdown или HTML
val categoryId: String,
val updatedAt: Long,
val searchIndex: String // нормализованный текст для FTS
)
@Entity(tableName = "kb_categories")
data class KbCategory(
@PrimaryKey val id: String,
val title: String,
val parentId: String?,
val position: Int
)
Синхронизация по updatedAt: при каждом запуске скачиваем только изменённые статьи с момента последнего sync-timestamp.
Zendesk Help Center / Freshdesk Solutions
Если поддержка уже на Zendesk — Help Center API предоставляет статьи напрямую. SDK Zendesk показывает их через встроенный UI, но он слабо кастомизируем. Для кастомного дизайна используем Zendesk Guide API:
GET https://yoursubdomain.zendesk.com/api/v2/help_center/articles.json
Response содержит body в HTML — рендерим через WebView с кастомным CSS, соответствующим дизайн-системе приложения.
Полнотекстовый поиск
Поиск по тысяче статей на сервере при каждом запросе — лишний round-trip. Для мобильного приложения лучше локальный Full-Text Search.
Android — Room FTS4:
@Fts4(contentEntity = KbArticle::class)
@Entity(tableName = "kb_articles_fts")
data class KbArticleFts(
val title: String,
val searchIndex: String
)
@Dao
interface KbSearchDao {
@Query("SELECT * FROM kb_articles WHERE id IN " +
"(SELECT rowid FROM kb_articles_fts WHERE kb_articles_fts MATCH :query)")
suspend fun search(query: String): List<KbArticle>
}
iOS — CoreData с NSPredicate или SQLite FTS5:
// NSPredicate для CoreData
let predicate = NSPredicate(
format: "title CONTAINS[cd] %@ OR content CONTAINS[cd] %@",
query, query
)
Для больших баз (>500 статей) — SQLite с FTS5 через GRDB.swift:
try db.create(virtualTable: "articles_fts", using: FTS5()) { t in
t.column("title")
t.column("body")
t.tokenizer = .unicode61()
}
FTS5 с unicode61 токенайзером поддерживает кириллицу — важно для русскоязычных приложений.
Рендеринг Markdown/HTML
Статьи часто хранятся в Markdown. Варианты рендеринга:
| Подход | iOS | Android | Плюсы | Минусы |
|---|---|---|---|---|
| WebView | WKWebView | WebView | Полный HTML/CSS | Медленный скролл, сложная навигация |
| Native Markdown | Down (lib) |
Markwon |
Нативный TextKit | Ограниченный CSS |
| AttributedString | iOS 15+ | — | Без зависимостей | Только базовый Markdown |
Markwon для Android поддерживает таблицы, code blocks с подсветкой синтаксиса и изображения — достаточно для технической документации.
Аналитика и обратная связь по статьям
Кнопка «Была ли статья полезна?» — простой механизм оценки качества контента. Отправляем событие с article_id и helpful: true/false в Firebase Analytics. Статьи с высоким процентом «не полезна» — кандидаты на переработку.
Analytics.logEvent("kb_article_feedback", parameters: [
"article_id": article.id,
"helpful": isHelpful ? "yes" : "no",
"time_spent_seconds": Int(Date().timeIntervalSince(openedAt))
])
time_spent_seconds даёт дополнительный сигнал: если пользователь прочитал за 3 секунды и нажал «не полезна» — статья не по теме. Если провёл 5 минут и нажал «полезна» — контент глубокий и релевантный.
Offline-доступ
База знаний должна работать без интернета — пользователь может обращаться к документации в зоне без сети. Все статьи после первой загрузки хранятся локально. Изображения кешируются через Kingfisher (iOS) или Coil (Android) с настройкой максимального размера кеша.
Процесс работы
Аудит источника контента и принятие решения об архитектуре (headless CMS, helpdesk API или собственный бэкенд).
Проектирование схемы данных с учётом иерархии категорий и поиска.
Реализация: синхронизация, локальное хранение, FTS, рендеринг контента.
UI: навигация по категориям, экран статьи, поиск с подсветкой совпадений.
Аналитика и offline-режим.
Ориентиры по срокам
Базовая база знаний с remote API, поиском и offline-режимом — 1–2 недели. Интеграция с Zendesk Help Center, кастомный Markdown-рендеринг и аналитика — до 3 недель.







