Как подключить мобильный SDK к приложению Flutter
Обновлено: 9 октября 2026 · 9 мин чтения
Плагин clomni_flutter работает поверх нативных SDK для Android и iOS, экраны нативные.
Шаги
-
1
Требования
- Flutter 3.16 или новее.
- iOS 15, Android API 24.
- App ID и оба ключа API (
android_…,ios_…). - Голосовым сообщениям (с SDK 1.0.2) нужно
RECORD_AUDIOв манифесте Android-приложения, иначе кнопка микрофона не показывается. Камере разрешение не нужно.
-
2
Установка
flutter pub add clomni_flutter
SDK для iOS является Swift package:
- Со Swift Package Manager плагин берёт SDK сам. В текущем Flutter он включён по умолчанию. Во Flutter 3.24 и новее, если он выключен, включите его командой
flutter config --enable-swift-package-manager. - С CocoaPods добавьте эту строку в
ios/Podfileвнутриtarget 'Runner'и выполнитеpod install. Без строкиpod installостанавливается с «clomni_flutter: the iOS SDK is not on CocoaPods trunk».
pod 'ClomniMessenger', :git => 'https://github.com/clomni/clomni-mobile-sdk.git', :tag => '1.0.4'
Добавьте тексты разрешений для фото (
NSPhotoLibraryUsageDescription,NSCameraUsageDescription, а с SDK 1.0.2 иNSMicrophoneUsageDescription) вios/Runner/Info.plist.На Android
MainActivityдолжна наследоватьFlutterFragmentActivity, а неFlutterActivity. Иначе приложение падает при открытии Messenger, а плавающая кнопка не видна:// android/app/src/main/kotlin/com/example/app/MainActivity.kt package com.example.app import io.flutter.embedding.android.FlutterFragmentActivity class MainActivity : FlutterFragmentActivity()
- Со Swift Package Manager плагин берёт SDK сам. В текущем Flutter он включён по умолчанию. Во Flutter 3.24 и новее, если он выключен, включите его командой
-
3
Запустите SDK
import 'dart:io' show Platform; import 'package:clomni_flutter/clomni_flutter.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Clomni.initialize('app_…', Platform.isIOS ? 'ios_…' : 'android_…'); if (kDebugMode) await Clomni.setLogLevel(ClomniLogLevel.debug); runApp(const App()); } -
4
Пользователь и Messenger
await Clomni.loginUser( const ClomniUser(userId: '12345', email: '[email protected]', name: 'Aysel'), userHash: hashFromYourServer, ); await Clomni.updateUser(language: 'az', customAttributes: {'plan': 'premium'}); // Together with your app's own logout: await Clomni.logout();
class SupportTile extends StatelessWidget { const SupportTile({super.key}); @override Widget build(BuildContext context) { return StreamBuilder<int>( stream: Clomni.unreadCountStream, // the current count at once, then every change builder: (context, snapshot) { final unread = snapshot.data ?? 0; return ListTile( title: const Text('Support'), trailing: unread > 0 ? Badge(label: Text('$unread')) : null, onTap: () => Clomni.present(source: 'profile_support'), ); }, ); } }Другие вызовы:
presentNewConversation(source: …),presentConversation(id),dismiss(),setLauncherVisible(true),setBottomPadding(72). События приходят как Stream:onMessengerOpened,onMessengerClosed,onConversationStarted,onFlowCompleted.Шрифты из
pubspec.yamlне доходят до нативных экранов. Передайте вsetTypefaceна iOS имя семейства шрифта изUIAppFonts, на Android имя ресурсаres/font:await Clomni.setTypeface(Platform.isIOS ? 'Montserrat' : 'montserrat');.Пока пользователь вошёл в приложение, вызывайте
loginUserпри каждом запуске, как будто он только что вошёл. Для того же пользователя SDK использует сохранённую сессию. -
5
Flow, события, ссылки и внешний вид
Запуск flow из приложения и подписка на события Messenger:
await Clomni.startFlow('ride_problem', data: {'ride_id': 'R-1923'}, openMessenger: true, source: 'ride_screen'); final subscriptions = [ Clomni.onMessengerOpened.listen((source) => debugPrint('opened from $source')), Clomni.onMessengerClosed.listen((_) => debugPrint('closed')), Clomni.onConversationStarted.listen((id) => debugPrint('conversation $id')), Clomni.onFlowCompleted.listen((flowId) => debugPrint('flow $flowId')), ]; // later: for (final s in subscriptions) { s.cancel(); }Flow должен быть создан в панели с триггером «Событие приложения» с тем же именем и опубликован. Данные должны быть JSON.
Ссылки, язык Messenger, звуки и собственный цвет приложения:
import 'package:url_launcher/url_launcher.dart'; await Clomni.onLink((url) => launchUrl(Uri.parse(url))); // or your own router; null: the system opens links await Clomni.setLanguage('en'); // 'az', 'en', 'ru'; null follows the phone await Clomni.setSoundsEnabled(false); await Clomni.setTheme(primaryColor: '#0A66C2', typeface: 'Montserrat', mode: ClomniThemeMode.dark);Язык Messenger меняет
setLanguage;updateUser(language: …)записывает язык в профиль пользователя. Выбранный язык должен быть включён в панели, иначе используется язык телефона, а если и он выключен, основной язык панели. Цвет указывается в формате#RRGGBB. Значения из панели действуют, только если приложение не задало свои. -
6
Push: Android
Сначала загрузите ключи в панель (статья «Ключи push для мобильного SDK»). Настройте Firebase через FlutterFire (
flutterfire configure) и объявите<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />вandroid/app/src/main/AndroidManifest.xml.import 'dart:io' show Platform; import 'package:clomni_flutter/clomni_flutter.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; // Clomni data messages while the app is in the background or closed: the SDK shows the notification. @pragma('vm:entry-point') Future<void> onBackgroundMessage(RemoteMessage message) async { await Clomni.handlePush(message.data); } Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); FirebaseMessaging.onBackgroundMessage(onBackgroundMessage); await Clomni.initialize('app_…', Platform.isIOS ? 'ios_…' : 'android_…'); runApp(const App()); } Future<void> setUpAndroidPush() async { final messaging = FirebaseMessaging.instance; await messaging.requestPermission(); // Android 13+: the system permission dialog final token = await messaging.getToken(); if (token != null) await Clomni.setDeviceToken(token); messaging.onTokenRefresh.listen(Clomni.setDeviceToken); // Messages while the app is open. FirebaseMessaging.onMessage.listen((message) async { if (!await Clomni.handlePush(message.data)) { // your app's own push } }); await Clomni.setNotificationIcon('ic_notification'); // android/app/src/main/res/drawable/ic_notification.png }Вызывайте
setUpAndroidPush()на Android в подходящий момент, например после входа. -
7
Push: iOS
Clomni отправляет push на iOS в APNs, не через Firebase.
firebase_messagingне видит нажатия на уведомление Clomni, поэтому ловите нажатие в нативном коде Runner:- В Xcode (
ios/Runner.xcworkspace): Runner › Signing & Capabilities › + Capability › Push Notifications. - Код Runner импортирует
ClomniMessenger. С CocoaPods достаточно строки Podfile выше. Со Swift Package Manager добавьте пакет и в цель Runner: File › Add Package Dependencies,https://github.com/clomni/clomni-mobile-sdk.git, продуктClomniMessenger, цель Runner. - Добавьте этот файл в Runner:
// ios/Runner/ClomniNotifications.swift import ClomniMessenger import UserNotifications /// Clomni pushes: hidden while the Messenger is open, and a tap opens the conversation. final class ClomniNotifications: NSObject, UNUserNotificationCenterDelegate { static let shared = ClomniNotifications() func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void ) { let show = Clomni.shouldShowForeground(notification.request.content.userInfo) completionHandler(show ? [.banner, .list, .sound] : []) } func userNotificationCenter( _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void ) { _ = Clomni.handlePush(response.notification.request.content.userInfo) completionHandler() } }- Сделайте его делегатом в
AppDelegate.swift, до `super.application(...)`:
// ios/Runner/AppDelegate.swift import Flutter import UIKit import UserNotifications @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { UNUserNotificationCenter.current().delegate = ClomniNotifications.shared GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }- Передайте токен APNs из Dart:
if (Platform.isIOS) { await FirebaseMessaging.instance.requestPermission(); final apnsToken = await FirebaseMessaging.instance.getAPNSToken(); // hex if (apnsToken != null) await Clomni.setDeviceToken(apnsToken); }Если на iOS нет Firebase, переопределите в
AppDelegatedidRegisterForRemoteNotificationsWithDeviceToken:Clomni.setDeviceToken(deviceToken), затемsuper. - В Xcode (
-
8
Проблемы
pod installостанавливается и печатает строкуpod 'ClomniMessenger': впишите строку внутрьtarget 'Runner'или включите Swift Package Manager.- Android: приложение падает при открытии Messenger или плавающая кнопка не видна:
MainActivityдолжна наследоватьFlutterFragmentActivity. - На Android уведомления не приходят, когда приложение закрыто: зарегистрируйте
onBackgroundMessageдоrunApp, функцией верхнего уровня. - iOS:
No such module 'ClomniMessenger': добавьте пакет или pod в цель Runner (шаг 2). - На iOS нажатие только открывает приложение: делегата нет или он назначен после
super.application(...).
Ошибки Dart начинаются с
[Clomni]в логе Flutter, нативные логи в logcat (Clomni) и в консоли Xcode. -
9
Полное руководство
- PDF: руководство Clomni Mobile SDK, на русском языке.
- Онлайн: Flutter (на английском).
- В панели: раздел «Guide» в колонке настроек канала.