Внедрение в жизненный цикл приложения
Описание процесса интеграции ChatCenterUI SDK, с синхронизацией жизненных циклов основного приложения (App Lifecycle) и SDK.
Общая схема взаимодействия
Диаграмма ниже демонстрирует, как события жизненного цикла приложения должны инициировать соответствующие методы SDK для типовой интеграции.
1. Запуск приложения
Инициализацию SDK рекомендуется проводить в классе Application в методе onCreate(), чтобы SDK был готов к обработке входящих push-уведомлений независимо от того, какая Activity запущена.
Создание экземпляра класса ChatCenterUI происходит максимально быстро и в процессе не выполняется никаких сетевых запросов.
Файл: MyApp.kt
import android.app.Application
import edna.chatcenter.ui.visual.core.ChatCenterUI
import edna.chatcenter.ui.visual.ChatConfig
import edna.chatcenter.core.config.transport.ChatTransportConfig
import edna.chatcenter.core.config.transport.ChatNetworkConfig
class MyApp : Application() {
lateinit var chatCenterUI: ChatCenterUI
override fun onCreate() {
super.onCreate()
// Конфигурацию ChatConfig обычно создают здесь же.
// Подробное описание полей — см. раздел «Настройки → ChatConfig».
val chatConfig = ChatConfig(
transportConfig = ChatTransportConfig(cloudHost = "https://your.edna.ru"),
networkConfig = ChatNetworkConfig()
)
// Конструктор: ChatCenterUI(appContext: Context, logger: ChatLoggerConfig? = null).
// Второй параметр опционален — если не нужен кастомный логгер, его можно опустить.
chatCenterUI = ChatCenterUI(applicationContext).apply {
// providerUid — уникальный идентификатор приложения, выданный edna.
// Доступна также перегрузка init(providerUid, appMarker, config) — три параметра.
init("YOUR_PROVIDER_UID", chatConfig)
}
}
}
Объект ChatCenterUI имеет смысл хранить как Singleton (через класс Application или DI), чтобы к нему был доступ из любых слоёв приложения.
logger: ChatLoggerConfig? — необязательный второй параметр конструктора ChatCenterUI. Подробнее о настройке логгера см. Расширенные настройки → Логгер.
2. Авторизация пользователя
После того как ваше приложение авторизовало пользователя (например, выполнен вход в авторизованную зону), необходимо сообщить SDK данные пользователя. Это позволяет загрузить историю переписки конкретного клиента.
Файл: AuthViewModel.kt
import edna.chatcenter.ui.visual.core.ChatCenterUI
import edna.chatcenter.core.config.ChatUser
// chatCenterUI — экземпляр ChatCenterUI, полученный через DI или из Application
fun handleSuccessfulLogin(
chatCenterUI: ChatCenterUI,
userId: String,
userName: String,
userEmail: String?
) {
// Формируем объект пользователя.
// identifier — неизменяемый идентификатор клиента в вашей системе (uuid), обязателен и не должен быть пустым.
// name — отображаемое имя клиента (опционально).
// data — произвольные дополнительные атрибуты (опционально); SDK не интерпретирует ключи,
// конкретный набор согласуйте с командой интеграции — см. ../methods/auth.md.
val chatUser = ChatUser(
identifier = userId,
name = userName,
data = userEmail?.let { mapOf("clientEmail" to it) }
)
// Авторизация в SDK (auth = null, если ChatAuth не используется).
chatCenterUI.authorize(chatUser, null)
}
3. Открытие чата
SDK предоставляет готовый ChatFragment, который можно встроить в Activity через FragmentManager или через Navigation Component.
Файл: MainActivity.kt
import edna.chatcenter.core.annotation.OpenWay
import edna.chatcenter.ui.visual.fragments.ChatFragment
fun openSupportChat() {
// Получаем экземпляр SDK (например, через DI или из Application)
val chatCenterUI = (application as MyApp).chatCenterUI
// getChatFragment() возвращает ранее созданный экземпляр (если он жив в памяти)
// или null. При первом открытии создайте фрагмент через ChatFragment.newInstance(...).
val chatFragment = chatCenterUI.getChatFragment()
?: ChatFragment.newInstance(OpenWay.DEFAULT)
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, chatFragment)
.addToBackStack(null)
.commit()
}
Прямая навигация через navigate(R.id.action_global_chatFragment) не сработает: Navigation Component инстанцирует фрагмент через FragmentFactory без аргументов, а ChatFragment ожидает аргументы, выставленные в ChatFragment.newInstance(@OpenWay from: Int). Если используете Navigation Component, добавляйте фрагмент, полученный из getChatFragment() / newInstance(...), в контейнер вручную через FragmentManager, либо зарегистрируйте кастомный FragmentFactory, который сам вызывает ChatFragment.newInstance(...).
Перед открытием чата убедитесь, что пользователь уже авторизован в SDK (см. раздел «Авторизация пользователя»). Сам метод getChatFragment() не валидирует авторизацию: он только возвращает ранее созданный ChatFragment (WeakReference), который заполняется при вызове ChatFragment.newInstance(...). Без предварительной авторизации ChatFragment отобразит экран с ошибкой загрузки истории.
Доступные значения OpenWay: OpenWay.DEFAULT — обычное открытие, OpenWay.FROM_PUSH — открытие из пуш-уведомления (см. edna.chatcenter.core.annotation.OpenWay).
4. Выход пользователя
При выходе пользователя из аккаунта в приложении необходимо разорвать сессию в SDK. У SDK для этого два метода с разной семантикой — выбор зависит от сценария:
| Сценарий выхода в приложении | Вызвать |
|---|---|
| Пользователь нажал «Выйти из аккаунта» | logout() |
| Пользователь вышел из авторизованной зоны (пин-код), но остаётся в приложении | deauthorizeUser() |
Полное описание контракта обоих методов — что они отправляют на сервер, что чистят локально, поведение при неактивном WebSocket, отдельный caveat про FCM/HCM-токены — в каноническом разделе Авторизация → Логаут.
Файл: ProfileViewModel.kt
import edna.chatcenter.ui.visual.core.ChatCenterUI
// Полный выход — клиент уведомляет сервер, локальные данные сессии очищаются.
// Контракт — см. ../methods/auth.md#логаут
fun performLogout(chatCenterUI: ChatCenterUI) {
chatCenterUI.logout()
navigateToLoginScreen()
}
// Выход из авторизованной зоны (пин-код) — соединение с сервером не разрывается,
// история сохраняется. Контракт — см. ../methods/auth.md#логаут
fun performDeauthorize(chatCenterUI: ChatCenterUI) {
chatCenterUI.deauthorizeUser()
navigateToLoginScreen()
}
При повторном входе в авторизованную зону необходимо повторно вызвать authorize(...) с данными пользователя.