Внедрение в жизненный цикл приложения
Описание процесса интеграции ChatCenterUI SDK, с синхронизацией жизненных циклов основного приложения (App Lifecycle) и SDK.
Общая схема взаимодействия
Диаграмма ниже демонстрирует, как события жизненного цикла приложения должны инициировать соответствующие методы SDK для типовой интеграции.
1. Запуск приложения
Инициализация SDK должна происходить как можно раньше, обычно в методе application(_:didFinishLaunchingWithOptions:). Это критично для корректной работы и минимизации возможных ошибок интеграции.
Создание экземпляра класса ChatCenterUISDK происходит максимально быстро и в процессе не выполняется никаких сетевых запросов.
Файл: AppDelegate.swift
import ChatCenterUI
var chatCenterSDK: ChatCenterUISDK?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 1. Конфигурация (заглушка; заполните реальными URL/ключами)
let transport = ChatTransportConfig(cloudHost: "cloud.edna.ru")
let chatConfig = ChatConfig(transportConfig: transport)
// 2. Инициализация SDK
// providerUid — уникальный ID приложения, выданный edna
chatCenterSDK = ChatCenterUISDK(
providerUid: "YOUR_PROVIDER_UID",
chatConfig: chatConfig
)
return true
}
// Передача токена Push-уведомлений в SDK
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
ChatCenterUISDK.setDeviceToken(deviceToken)
}
2. Авторизация пользователя
После того как ваше приложение авторизовало пользователя (например, выполнен вход в авторизованную зону), необходимо сообщить SDK данные пользователя. Это позволяет загрузить историю переписки конкретного клиента.
Файл: AuthService.swift / LoginViewModel.swift
final class AuthService {
// Сохраните экземпляр ChatUser: обновления через updateData применяются
// только к тому объекту, который был передан в authorize(user:).
private var chatUser: ChatUser?
func handleSuccessfulLogin(userId: String, userName: String?) {
guard let chatCenterSDK = (UIApplication.shared.delegate as? AppDelegate)?.chatCenterSDK else { return }
let user = ChatUser(
identifier: userId, // устойчивый ID в вашей системе
name: userName, // опционально
data: ["segment": "premium"] // опционально, произвольные атрибуты, отображаемые в АРМ в профиле клиента
)
self.chatUser = user
// Авторизация пользователя в SDK
chatCenterSDK.authorize(user: user)
}
}
Обновление данных пользователя (опционально)
Если дополнительные данные становятся известны после авторизации, их можно дослать вызовом updateData на том же экземпляре ChatUser, который был передан в authorize(user:):
// Обновление данных пользователя после авторизации
self.chatUser?.updateData(data: ["email": "user@example.ru", "segment": "premium"])
Обновлённые данные отправятся на сервер при ближайшем подключении к чату — открытии экрана чата или переподключении. Повторное изменение данных требует нового вызова updateData.
Вызов updateData на новом экземпляре ChatUser (созданном повторно) не будет доставлен на сервер — используйте для обновлений только тот объект, который передавали в authorize(user:).
Предзаполнение сообщения (опционально)
Перед открытием чата можно задать текст, который будет подставлен в поле ввода:
// Предзаполнение поля ввода (текст подставляется однократно)
chatCenterSDK.prefill(message: "Здравствуйте, у меня вопрос по заказу №12345")
3. Открытие чата
Для отображения интерфейса чата SDK предоставляет готовый UIViewController. Его можно показать модально или запушить в ваш навигационный стек и т.д.
Файл: MainViewController.swift
@objc func openSupportChat() {
guard let chatCenterSDK = (UIApplication.shared.delegate as? AppDelegate)?.chatCenterSDK else { return }
// Получение контроллера чата
let result = Result { try chatCenterSDK.getChat() }
switch result {
case let .success(chatController):
// Открытие экрана чата
// Вариант А: Push (если есть NavigationController)
self.navigationController?.pushViewController(chatController, animated: true)
// Вариант Б: Modal
// self.present(chatController, animated: true, completion: nil)
case let .failure(error):
// getChat() бросает ChatCenterUIError.userNotAuthorized, если пользователь не авторизован
print("Ошибка открытия чата: \(error)")
}
}
4. Выход пользователя
При выходе пользователя из аккаунта приложения необходимо разорвать сессию в SDK. Это удаляет локальные данные и отписывает устройство от пуш-уведомлений для этого пользователя.
Файл: ProfileViewModel.swift
func performLogout() {
guard let chatCenterSDK = (UIApplication.shared.delegate as? AppDelegate)?.chatCenterSDK else { return }
do {
// Очистка данных пользователя и разрыв соединения
try chatCenterSDK.logout()
print("Chat SDK: Logged out successfully")
} catch {
print("Chat SDK: Logout error: \(error)")
}
// Далее следует логика перехода на экран авторизации приложения
}
В случае наличия в приложении авторизованной зоны (закрытой вводом пин-кода) и необходимости завершения текущей сессии при выходе из нее, можно использовать метод deauthorizeUser(), для локального удаления пользователя и прекращения сетевой активности SDK.
func performLogout() {
guard let chatCenterSDK = (UIApplication.shared.delegate as? AppDelegate)?.chatCenterSDK else { return }
// Локальное удаление пользователя и разрыв соединения
chatCenterSDK.deauthorizeUser()
// Далее следует логика перехода на экран авторизации приложения
}
При повторном входе в авторизованную зону пользователь должен быть повторно установлен через метод authorize(user:auth:).
Потокобезопасность
Большинство методов SDK должны вызываться на главном потоке, так как они обращаются к UIKit и shared state.
| Метод | Требование к потоку | Примечания |
|---|---|---|
ChatCenterUISDK.init | Main thread | Инициализирует UI-компоненты |
authorize(user:auth:) | Main thread | Мутирует shared state |
getChat() | Main thread | Возвращает UIViewController |
send(message:) | Main thread | Обращается к WebSocket |
logout() / deauthorizeUser() | Main thread | Очищает state |
setDeviceToken(_:) | Любой поток | Постит Notification |
| Методы делегата | Фоновый поток | Диспатчите на DispatchQueue.main для UI |
Методы ChatCenterUISDKDelegate могут вызываться не на главном потоке. Если в обработчике вы обновляете UI, обязательно оберните вызов в DispatchQueue.main.async.