Flutter SDK 概述
Flutter SDK 讓你在 Flutter App(Android、iOS,另支援 macOS、Windows、Linux 桌面端)中接入 IM 服務:登入、長連線與斷線重連、前後臺切換、訊息收發、會話同步和本地資料庫都由 SDK 完成,你只需要把資料顯示出來。離線推送(APNs、FCM 和國內廠商通道)和音視訊通話(系統來電介面)由單獨的包提供,按需依賴。
import 'package:deeprespond_im_flutter/deeprespond_im_flutter.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// 接入推送时,Firebase.initializeApp()、FCM 的后台处理函数和厂商通道的注册放在这里,见“离线推送”
final im = await DRClient.create(DRClientOptions(
appKey: '1575529652#demo',
apiUrl: Uri.parse('https://im.example.com'),
platform: DRFlutterPlatform.instance,
));
if (im.auth.currentUser == null) {
await im.auth.loginWithTicket(ticket: await fetchTicketFromYourServer()); // 已登录过的,创建后自动恢复
}
final list = im.conversations.list(); // 会话列表:先显示本地数据,后台同步
runApp(MaterialApp(
home: LiveListBuilder<ConversationView>(
list: list,
builder: (context, snapshot) => ListView(children: [for (final c in snapshot.items) ListTile(title: Text(c.conversationKey))]),
),
));
}
| 專案 | 說明 |
|---|---|
| 當前版本 | 1.0.0-alpha.4,預釋出(版本與支援狀態) |
| 安裝 | flutter pub add deeprespond_im_flutter |
| 平臺 | Android 7.0、iOS 15、macOS 12、Windows 10、Linux(GTK 3)以上;不支援 Flutter Web |
| 環境 | Flutter 3.38.1、Dart 3.10 以上 |
| 介面參考 | pub.dev 上的 deeprespond_im API 文件 |
能做什麼
客戶端物件 im(DRClient)按功能分為以下幾個部分:
| 屬性 | 功能 | 文件 |
|---|---|---|
im.auth、im.connection、im.config | 登入、退出、修改密碼;連線狀態與診斷;應用的執行配置 | 初始化、登入與連線 |
im.conversations | 會話列表、未讀數、置頂、草稿、正在輸入 | 會話 |
im.messages | 訊息列表、傳送、撤回、表情回應、置頂、已讀回執、本地搜尋 | 訊息 |
im.users、im.friends、im.presence、im.devices | 本人與其他使用者的資料、好友與黑名單、線上狀態、本人的登入裝置 | 使用者、好友與線上狀態 |
im.groups | 群、群成員、入群申請與邀請、入群連結 | 群組 |
im.files | 上傳、下載、群檔案 | 檔案與圖片 |
im.chatrooms | 聊天室 | 聊天室 |
im.calls | 一對一和群組的語音、視訊通話 | 音視訊通話 |
im.channels | 獨立 RTC 頻道:加入、恢復、媒體、狀態與退出 | 頻道接入 |
im.push、im.reports | 新訊息提醒、推送設定、會話免打擾;舉報 | 提醒、免打擾與舉報 |
im.events、im.on<T>()、DRException | 事件、錯誤與提示文案 | 事件與錯誤處理 |
另外,離線推送的登記、許可權和通知點選見離線推送;DRImage、LiveListBuilder、錄音等 Flutter 元件見在 Flutter 介面中使用。第一次接入請先看快速整合。
包的組成
只收發訊息的 App 只需要依賴 deeprespond_im_flutter 一個包,它同時匯出核心包的全部 API,程式碼中也只寫一個 import。離線推送、音視訊通話和國內廠商推送通道帶有較大的原生依賴,做成可選的包,用到時再新增。
| 包 | 內容 | 什麼時候需要 |
|---|---|---|
deeprespond_im_flutter | 全部模組的 API(DRClient)、資料型別、事件、錯誤;平臺實現 DRFlutterPlatform(前後臺、網路變化、安全儲存、裝置資訊)、原生的圖片和影片處理、錄音 VoiceRecorder、元件 DRImage、LiveListBuilder;顯示輔助 package:deeprespond_im_flutter/render.dart | 總是需要 |
deeprespond_im_push | 離線推送:APNs、FCM 的令牌登記,通知許可權,通知的點選,前臺時的顯示控制,Android 通知渠道(DRPush)。依賴 firebase_core、firebase_messaging | 需要 App 不在前臺時收到新訊息提醒 |
deeprespond_im_push_huawei、_honor、_xiaomi、_oppo、_vivo、_meizu | 國內廠商的推送通道,只有 Android | 在中國大陸釋出、需要在沒有 Google 服務的手機上收到推送 |
deeprespond_im_call | 音視訊通話:媒體連線、通話畫面元件、系統來電介面(iOS 的 CallKit 與 PushKit,Android 的全屏來電通知與 Core-Telecom)、忙線檢測。依賴 deeprespond_im_push | 需要語音、視訊通話 |
核心 API 實際位於純 Dart 的 deeprespond_im 包中,由 deeprespond_im_flutter 自動帶入並匯出,Flutter App 不需要另外依賴它;只有不使用 Flutter 的 Dart 程式(命令列工具、Dart VM 中的測試)才直接依賴它。
推送包和來電包依賴了即生效:它們在 Flutter 註冊外掛時自動接入客戶端,你只需在建立客戶端時給出 push、call 選項(不給時對應的功能不啟用)。廠商通道的包要在 main() 中呼叫各自的註冊函式,見離線推送。
執行環境
| 平臺 | 最低版本 | 推送 | 來電 |
|---|---|---|---|
| Android | 7.0(API 24) | FCM 和國內廠商通道(華為、榮耀、小米、OPPO、vivo、魅族) | 全屏來電通知和 Core-Telecom |
| iOS | 15.0 | APNs,另可登記 VoIP 推送(PushKit) | CallKit(在中國大陸 App Store 上架的版本不能使用,見音視訊通話) |
| macOS | 12.0 | APNs(可選) | 應用內的介面 |
| Windows | 10 | 不提供 | 應用內的介面 |
| Linux | x64、Arm64,GTK 3 | 不提供 | 應用內的介面 |
- Flutter 和 Dart:Flutter 3.38.1 以上,Dart 3.10 以上。
- Android:各包的
minSdk為 24,以compileSdk36 編譯,需要 JDK 17。App 的minSdk不能低於 24,compileSdk建議使用 36。 - iOS、macOS:App 的部署目標不能低於 iOS 15.0、macOS 12.0(Xcode 工程和
Podfile中都要設定)。原生部分同時提供 CocoaPods 和 Swift Package Manager 的配置,兩種方式都可以使用。 - 桌面端:Windows、Linux 上收發訊息、會話、群組、檔案、聊天室等功能與移動端相同,但沒有系統推送,App 關閉後收不到提醒;錄音(
VoiceRecorder)只支援 Android 和 iOS,其他平臺丟擲unsupported。桌面端的連線一直按前臺處理,最小化或失去焦點不影響連線。 - 不支援 Flutter Web:網頁請使用 Web SDK。
安裝
各包釋出在 pub.dev 的 deeprespond.cn,當前為 1.0.0-alpha.4 預釋出版本,變更記錄見各包頁面的 Changelog。1.0.0-alpha.4 起只需依賴 deeprespond_im_flutter;從更早的版本升級時,可以刪除對 deeprespond_im 的依賴,並把 package:deeprespond_im/deeprespond_im.dart、package:deeprespond_im/render.dart 的 import 改為 package:deeprespond_im_flutter/deeprespond_im_flutter.dart、package:deeprespond_im_flutter/render.dart,原來的寫法仍然可用。在 App 的 pubspec.yaml 中加入依賴:
dependencies:
deeprespond_im_flutter: ^1.0.0-alpha.4
# 需要离线推送时
deeprespond_im_push: ^1.0.0-alpha.4
# 需要音视频通话时
deeprespond_im_call: ^1.0.0-alpha.4或者用命令新增:
flutter pub add deeprespond_im_flutter所有包使用同一個版本號,一起釋出,請讓它們保持相同的版本。
許可權
| 平臺 | 許可權 | 由誰宣告 |
|---|---|---|
| Android | INTERNET、ACCESS_NETWORK_STATE、RECORD_AUDIO(錄音) | deeprespond_im_flutter 的清單已宣告,構建時自動合併,App 不需要再寫 |
| Android | POST_NOTIFICATIONS(Android 13 起的通知許可權) | deeprespond_im_push 的清單已宣告;執行時的授權請求見離線推送 |
| Android | CAMERA、MODIFY_AUDIO_SETTINGS、BLUETOOTH_CONNECT、MANAGE_OWN_CALLS、USE_FULL_SCREEN_INTENT、前臺服務(FOREGROUND_SERVICE 及 PHONE_CALL、MICROPHONE、CAMERA 型別)等通話所需的許可權 | 只在 deeprespond_im_call 的清單中宣告,不用通話的 App 不會帶上它們,見音視訊通話 |
| iOS | NSMicrophoneUsageDescription(麥克風的用途說明,錄音和通話) | App 在 Info.plist 中寫入,必需 |
| iOS | 推送、來電的能力和後臺模式(remote-notification、voip、audio) | App 在 Xcode 中新增,見離線推送、音視訊通話 |
| iOS | NSCameraUsageDescription(攝像頭的用途說明,視訊通話) | 使用視訊通話的 App 在 Info.plist 中寫入 |
| macOS | 網路訪問(com.apple.security.network.client)和鑰匙串(keychain-access-groups)的權利;使用錄音、通話時另需麥克風、攝像頭的用途說明 | App 在 entitlements 和 Info.plist 中寫入 |
執行時的麥克風、攝像頭授權由 SDK 在錄音、通話時請求,使用者拒絕時丟擲 permission_required(details['permissions'] 列出缺少的許可權)。各平臺的完整配置(部署目標、備份規則、開發時的明文請求等)見快速整合。
顯示輔助與提示文案
deeprespond_im_flutter 包中另有一個按需匯入的庫 package:deeprespond_im_flutter/render.dart:
| 內容 | 說明 |
|---|---|
| 顯示輔助 | displayName(使用者的顯示名,按好友備註、群暱稱、暱稱、使用者名稱取第一個非空的)、conversationTitle(會話標題)、summarize(會話列表中最後一條訊息的摘要)、renderTip(群提示的文字)、renderCallRecord(通話記錄的文字)、renderRecall(撤回提示),用法見訊息 |
| 提示文案 | zhCN(中文文案表,可以整體替換為其他語言)、describeError(按錯誤碼給出提示文字),見事件與錯誤處理 |
import 'package:deeprespond_im_flutter/render.dart';基本概念
客戶端物件
DRClient.create() 建立客戶端(非同步),整個 App 共用這一個:同一程序中同一個 AppKey 只有一個客戶端,再次呼叫返回同一個物件。客戶端與程序同生命週期,沒有釋放的方法。建立時讀取本地儲存的登入狀態,這臺裝置上已經登入過的,SDK 立即恢復登入,你不必再呼叫登入。詳見初始化、登入與連線。
可訂閱的列表
會話列表、訊息列表、好友列表、群成員列表等會持續變化的資料,以可訂閱的物件(LiveList,訊息列表為 MessageList)提供:
import 'package:deeprespond_im_flutter/deeprespond_im_flutter.dart';
final list = im.conversations.list();
final sub = list.stream.listen((snapshot) {
// 订阅时先收到当前快照,之后每次变化收到新快照
print('${snapshot.items.length} 个会话,loading=${snapshot.loading},hasMore=${snapshot.hasMore}');
});
// 不再显示时
await sub.cancel();
list.dispose();snapshot是當前的快照,同步讀取;stream在訂閱時先發出當前快照,之後每次變化發出新快照,dispose()後結束。- 新快照中沒有變化的條目仍是原來的物件,
ListView的條目可以按引用判斷是否需要重建。快照和其中的資料都不可修改。 - 同一輪事件迴圈中的多次變化合併為一次通知。
- 在 Widget 中用
LiveListBuilder訂閱並重建介面,見在 Flutter 介面中使用。 - 不再顯示時呼叫
dispose()釋放。退出登入、切換使用者時 SDK 先把快照清空並通知一次,再釋放全部列表。
登入狀態、連線狀態、未讀總數等單個的值可以同步讀取(如 im.auth.state、im.conversations.getUnreadTotal()),變化時發出對應的事件。
資料物件
服務端的物件(訊息、會話、使用者、群等)以只讀的型別化物件交給你:常用欄位為 camelCase 的屬性(如 message.clientMsgId、conversation.unreadCount),時間為 DateTime(UTC),ID 為 String。每個物件的 raw 儲存服務端返回的原始 JSON(欄位名與服務端 REST API 相同,如 client_msg_id),服務端以後新增的欄位不必等 SDK 升級,就可以從 raw 中讀取。
本地優先,後臺同步
會話列表、訊息、好友、群等資料都儲存在 App 沙盒中的本地資料庫裡,你讀到的總是本地的資料:App 啟動後立即顯示上次的內容,不必等待網路。SDK 在後臺連線長連線、同步變化,寫入本地後再通知你。離線時傳送的訊息進入傳送佇列,網路恢復後自動發出;App 被關閉後再次開啟,佇列中的訊息繼續傳送。
前後臺與推送
在 Android 和 iOS 上,SDK 自動跟蹤 App 的前後臺狀態:App 切到後臺時 SDK 通知服務端,之後的新訊息由服務端以推送送達(需要接入離線推送);回到前臺時立即恢復連線並同步。你不需要處理前後臺切換,詳見前後臺與網路變化。
與服務端的關係
Flutter SDK 只呼叫 IM 服務的客戶端介面,使用者的身份由你的業務服務端擔保:
- 你的業務服務端用 App Token 呼叫 IM 服務的 REST API,為使用者建立 IM 賬號,並在使用者登入你的業務系統後為他簽發登入憑證;
- App 從你的業務服務端取得憑證,交給 SDK 登入 IM;
- 之後收發訊息、同步會話都由 SDK 直接與 IM 服務通訊。
App Token 和 Client Secret 是服務端憑據,不能出現在 App 中。AppKey(org_name#app_name)是應用的公開標識,可以寫在 App 中,在控制檯的應用詳情中檢視。推送使用的證書和金鑰在控制檯的推送憑據中配置,App 中只寫憑據的名稱。
與 Web SDK 的區別
Flutter SDK 由 Web SDK 移植而來,模組、方法和行為基本相同,主要的區別是:
| Web SDK | Flutter SDK |
|---|---|
createDRClient() 同步建立;destroy() 釋放 | DRClient.create() 非同步建立,與程序同生命週期,重複呼叫返回同一個客戶端 |
| 資料物件的欄位為服務端的 snake_case 欄位名 | 型別化的物件,欄位為 camelCase,另有 raw |
im.on('message.received', fn) | im.on<MessageReceived>() 返回 Stream;全部事件為 im.events |
list.getSnapshot()、list.subscribe() | list.snapshot、list.stream |
DRError、AbortSignal | DRException、DRCancelToken |
資料儲存在 IndexedDB,令牌儲存在 localStorage | 資料儲存在 SQLite(可選加密),令牌儲存在系統的安全儲存(鑰匙串、Keystore) |
| 多個標籤頁共用一個連線 | 一個程序一個客戶端;後臺 isolate 中使用輕量的 DRBackgroundClient |
| 瀏覽器通知 | 系統推送(APNs、FCM、國內廠商通道)、角標、系統來電介面 |
獨立 RTC 頻道
im.channels 用於會議、語音房等不建群的音影片頻道,呼叫方式、媒體許可權和前後臺處理見頻道接入,各平臺的支援情況見版本與支援狀態。
