环境 | 版本 |
Flutter | SDK 最低要求 Flutter 2.2.0版本,TUIKit 集成组件库最低要求 Flutter 2.10.0 版本。 |
Android | Android Studio 3.5及以上版本,App 要求 Android 4.1及以上版本设备。 |
iOS | Xcode 11.0及以上版本,请确保您的项目已设置有效的开发者签名。 |
腾讯云IM SDK |
invokeMethod
,监听另一端发来的方法调用使用预挂载的Method Channel监听器。flutter build aar
settings.gradle
中:// Include the host app project.include ':app' // assumed existing content// Add the following lines to your projectsetBinding(new Binding([gradle: this]))evaluate(new File(settingsDir.parentFile,'tencent_chat_module/.android/include_flutter.groovy'))
app/build.gradle => dependencies
中引入对 Flutter module 的 implementation
:dependencies {implementation project(':flutter')}
// 上一步构建的 Flutter Module 的路径flutter_chat_application_path = '../tencent_chat_module'load File.join(flutter_chat_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'MyApp' doinstall_all_flutter_pods(flutter_chat_application_path)end
post_install
块中,调用 flutter_post_install(installer)
,并完成 腾讯云IM TUIKit 所需的权限声明,包括麦克风权限/相机权限/相册权限。post_install do |installer|flutter_post_install(installer) if defined?(flutter_post_install)installer.pods_project.targets.each do |target|flutter_additional_ios_build_settings(target)target.build_configurations.each do |config|config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)','PERMISSION_MICROPHONE=1','PERMISSION_CAMERA=1','PERMISSION_PHOTOS=1',]endendend
pod install
。tencent_chat_module/pubspec.yaml
中更改 Flutter 插件依赖时,请在 Flutter Module 目录中运行 flutter pub get
以刷新 podhelper.rb
脚本读取的插件列表。然后,从您 iOS 应用程序的根目录,再次执行 pod install
。arch -x86_64 pod install --repo-update
。podhelper.rb
脚本将您的插件 / Flutter.framework
/ App.framework
植入您的项目中。flutter build ios-framework
.some/path/MyApp/Flutter/
.flutter build ios-framework --output=some/path/MyApp/Flutter/
some/path/MyApp/Flutter/Release/
目录拖拽 frameworks 到你的应用 target 编译设置的 General > Frameworks, Libraries, and Embedded Content 下,然后在 Embed 下拉列表中选择 “Embed & Sign”。引擎模式 | 介绍 | 优点 | 缺点 | Demo 源码下载 |
Chat 模块和 Call 模块在同一个Flutter 引擎中承载。 | 方便,所有 Flutter 代码统一维护。 | 由于 Call 插件,在有电话呼入时,需要自动展示来电页面。如果在同一个引擎中,需要强制跳转至 Flutter 所在页面,体验较差。 | ||
Chat 模块和 Call 模块分别承载于不同的 Flutter 引擎中,使用 Flutter 引擎组来统一管理这两个引擎。 | Call 插件独立存在于一个 Flutter 引擎中,独立页面控制,来电时,直接将该页面弹窗即可,不影响用户当前所在页面,体验较好。 | 通话模块无法最小化成浮窗形式。 |
cd some/path/flutter create --template module tencent_chat_module
flutter run --debug
或 flutter build ios
。 您还可以使用 Flutter 和 Dart 插件在 Android Studio, IntelliJ 或 VS Code 中运行该模块。 该项目在嵌入到现有应用程序之前包含模块的单视图示例版本,这对于测试代码的仅 Flutter 部分很有用。tencent_chat_module
模块目录结构类似于普通的 Flutter 应用程序:tencent_chat_module/├── .ios/│ ├── Runner.xcworkspace│ └── Flutter/podhelper.rb├── lib/│ └── main.dart├── test/└── pubspec.yaml
lib/
中,编写代码了。lib/
我们创建三个目录,call
, chat
, common
。分别用于放置通话引擎,IM引擎,及通用model类。tencent_chat_module/├── lib/│ └── call/│ └── chat/│ └── common/
common/common_model.dart
文件,如下所示,新建两个class,用于定义Flutter与原生应用通信规范。class ChatInfo {String? sdkappid;String? userSig;String? userID;ChatInfo.fromJSON(Map<String, dynamic> json) {sdkappid = json["sdkappid"].toString();userSig = json["userSig"].toString();userID = json["userID"].toString();}Map<String, String> toMap(){final Map<String, String> map = {};if(sdkappid != null){map["sdkappid"] = sdkappid!;}if(userSig != null){map["userSig"] = userSig!;}if(userID != null){map["userID"] = userID!;}return map;}}class CallInfo{String? userID;String? groupID;CallInfo();CallInfo.fromJSON(Map<String, dynamic> json) {groupID = json["groupID"].toString();userID = json["userID"].toString();}Map<String, String> toMap(){final Map<String, String> map = {};if(userID != null){map["userID"] = userID!;}if(groupID != null){map["groupID"] = groupID!;}return map;}}
lib/chat
目录下。model.dart
。
该Model用于挂载初始化并管理腾讯云IM Flutter模块,离线推送能力,全局状态管理,维护与Native间通信。
是整个Chat模块的核心。
详细代码可查看Demo源码。重点关注三个部分:chat_main.dart
文件,用于Chat模块主入口。didChangeAppLifecycleState
监听与前后台切换事件上报,详情请查看离线推送插件文档步骤5。push.dart
文件,用于单例管理 离线推送插件 能力。用于获取并上报Token/获取推送权限等操作。详细代码可查看Demo源码。conversation.dart
文件,用于承载TUIKit的会话模块组件 TIMUIKitConversation
。详细代码可查看Demo源码。chat.dart
文件,用于承载TUIKit的历史消息列表和发送消息模块组件 TIMUIKitChat
。
该页面还有跳转至 Profile 及 Group Profile 页面的能力。
详细代码可查看Demo源码。user_profile.dart
文件,用于承载TUIKit的用户信息及关系链管理模块组件 TIMUIKitProfile
。详细代码可查看Demo源码。group_profile.dart
文件,用于承载TUIKit的群信息及群管理模块组件 TIMUIKitGroupProfile
。详细代码可查看Demo源码。tencent_chat_module/├── lib/│ └── call/│ └── chat.dart│ └── model.dart│ └── chat_main.dart│ └── push.dart│ └── conversation.dart│ └── user_profile.dart│ └── group_profile.dart│ └── chat/│ └── common/
lib/call
目录下。model.dart
。
该Model用于挂载初始化并管理 音视频通话插件,全局状态管理,维护与Native间通信。
是整个Call模块的核心。
详细代码可查看Demo源码。重点关注两个部分:call_main.dart
文件,用于Call模块主入口。
该组件用于注入音视频通话插件所需绑定的navigatorKey。
详细代码可查看Demo源码。lib/main.dart
文件,将 main()
方法改成一个空 MaterialApp 即可。main()
方法就没有被用上。void main() {WidgetsFlutterBinding.ensureInitialized();runApp(MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Container(),));}
@pragma('vm:entry-point')
注解,将该方法标记为一个 entry-point
入口。方法名 chatMain
即该入口的名称,在Native中,也使用该名称,创建对应Flutter引擎。ChangeNotifierProvider
状态管理,维护 ChatInfoModel
数据及业务逻辑。@pragma('vm:entry-point')void chatMain() {// This call ensures the Flutter binding has been set up before creating the// MethodChannel-based model.WidgetsFlutterBinding.ensureInitialized();final model = ChatInfoModel();runApp(ChangeNotifierProvider.value(value: model,child: const ChatAPP(),),);}
callMain
。ChangeNotifierProvider
状态管理,维护 CallInfoModel
数据及业务逻辑。@pragma('vm:entry-point')void callMain() {// This call ensures the Flutter binding has been set up before creating the// MethodChannel-based model.WidgetsFlutterBinding.ensureInitialized();final model = CallInfoModel();runApp(ChangeNotifierProvider.value(value: model,child: const CallAPP(),),);}
FlutterEngineGroup
(Flutter 引擎组),统一管理多个引擎实例。AppDelegate.swift
文件中,添加如下代码:@UIApplicationMainclass AppDelegate: FlutterAppDelegate {lazy var flutterEngines = FlutterEngineGroup(name: "chat.flutter.tencent", project: nil)...}
FlutterUtils.swift
文件,编写代码。本部分详细代码,可查看Demo源码。AppDelegate.swift
文件中,新增如下代码。具体代码,可以参考Demo源码。FlutterUtils.kt
文件,并定义 FlutterUtils
静态类。@SuppressLint("StaticFieldLeak")object FlutterUtils {}
FlutterEngineGroup
(Flutter 引擎组),统一管理多个引擎实例。FlutterUtils.kt
文件中,定义一个 FlutterEngineGroup
,及配套各个Flutter Engine实例和Method Channel,并在初始化时,将其初始化。lateinit var context : Contextlateinit var flutterEngines: FlutterEngineGroupprivate lateinit var chatFlutterEngine:FlutterEngineprivate lateinit var callFlutterEngine:FlutterEnginelateinit var chatMethodChannel: MethodChannellateinit var callMethodChannel: MethodChannel// 初始化flutterEngines = FlutterEngineGroup(context)...
MyApplication
中,初始化上述对象。MyApplication.kt
文件中,将全局context传入单例对象,并执行初始化。class MyApplication : MultiDexApplication() {override fun onCreate() {super.onCreate()FlutterUtils.context = this // newFlutterUtils.init() // new}}
点击后续动作
选择 打开应用内指定页面
,应用内页面
以 Activity
方式,配置一个用于处理离线推送信息的页面,建议为应用首页。如,我们的Demo配置为:com.tencent.chat.android.MainActivity
.cd some/path/flutter create --template module tencent_chat_module
flutter run --debug
或 flutter build ios
。 您还可以使用 Flutter 和 Dart 插件在 Android Studio, IntelliJ 或 VS Code 中运行该模块。 该项目在嵌入到现有应用程序之前包含模块的单视图示例版本,这对于测试代码的仅 Flutter 部分很有用。tencent_chat_module
模块目录结构类似于普通的 Flutter 应用程序:tencent_chat_module/├── .ios/│ ├── Runner.xcworkspace│ └── Flutter/podhelper.rb├── lib/│ └── main.dart├── test/└── pubspec.yaml
lib/
中,编写代码了。ChatInfoModel
中。_coreInstance.init()
及 _coreInstance.login()
初始化并登录腾讯云IM。并初始化音视频推送插件及离线推送插件,完成推送Token上报。push.dart
文件,用于单例管理 离线推送插件 能力。用于获取并上报Token/获取推送权限等操作。详细代码可查看Demo源码。conversation.dart
文件,用于承载TUIKit的会话模块组件 TIMUIKitConversation
。详细代码可查看Demo源码。chat.dart
文件,用于承载TUIKit的历史消息列表和发送消息模块组件 TIMUIKitChat
。
该页面还有跳转至 Profile 及 Group Profile 页面的能力。
详细代码可查看Demo源码。user_profile.dart
文件,用于承载TUIKit的用户信息及关系链管理模块组件 TIMUIKitProfile
。详细代码可查看Demo源码。group_profile.dart
文件,用于承载TUIKit的群信息及群管理模块组件 TIMUIKitGroupProfile
。详细代码可查看Demo源码。AppDelegate
中的app启动时创建一个FlutterEngine,并公开为一个属性。import UIKitimport Flutterimport FlutterPluginRegistrant@UIApplicationMainclass AppDelegate: FlutterAppDelegate { // More on the FlutterAppDelegate.lazy var flutterEngine = FlutterEngine(name: "tencent cloud chat")override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// Runs the default Dart entrypoint with a default Flutter route.flutterEngine.run();GeneratedPluginRegistrant.register(with: self.flutterEngine);return super.application(application, didFinishLaunchingWithOptions: launchOptions);}}
AppDelegate.swift
文件中,新增如下代码。具体代码,可以参考Demo源码。FlutterUtils.kt
文件,并定义 FlutterUtils
静态类。@SuppressLint("StaticFieldLeak")object FlutterUtils {}
FlutterEngine
(Flutter 引擎)。FlutterUtils.kt
文件中,定义一个 FlutterEngine
,并在初始化时,将其初始化。lateinit var context : Contextprivate lateinit var flutterEngine:FlutterEngine// 初始化flutterEngine = FlutterEngine(context)
MyApplication
中,初始化上述对象。MyApplication.kt
文件中,将全局context传入单例对象,并执行初始化。class MyApplication : MultiDexApplication() {override fun onCreate() {super.onCreate()FlutterUtils.context = this // newFlutterUtils.init() // new}}
点击后续动作
选择 打开应用内指定页面
,应用内页面
以 Activity
方式,配置一个用于处理离线推送信息的页面,建议为应用首页。如,我们的Demo配置为:com.tencent.chat.android.MainActivity
.import ImSDK_Plusfunc initTencentChat(){if(isLoginSuccess == true){return}let data = V2TIMManager.sharedInstance().initSDK( 您的SDKAPPID , config: nil);if (data == true){V2TIMManager.sharedInstance().login(chatInfo.userID,userSig: chatInfo.userSig,succ: {self.isLoginSuccess = trueself.reportChatInfo()},fail: onLoginFailed())}}
_coreInstance.setDataFromNative()
,将当前用户信息传入。final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();_coreInstance.setDataFromNative(userId: chatInfo?.userID ?? "");
本页内容是否解决了您的问题?