ChannelTalk SDK does not officially support Flutter.
And, it's not optimized for Flutter.
This guide is not an official support document, so it may differ from the latest version.
This guide was written in the following environment:
Flutter : 1.22.2
Android : minSdk 16 / targetSdk 29 / compileSdk 29
AndroidStudio : Android Studio 4.0.1 Build #AI-193.6911.18.40.6626763
Xcode : 12.0 (12A7209)
CocoaPod : 1.10.0.rc.1
Channel SDK - Android : 8.0.0
Channel SDK - iOS : 8.0.2
Android
Installation
Basically, it is the same as the native SDK installation.
Prerequisite
•
minSdkVersion ≥ 15
•
Android Support Library Version ≥ 27.1.0
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Groovy
복사
Step 1. Install ChannelIO
Declare our Maven repository to the build.gradle:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://maven.channel.io/maven2' }
}
}
Groovy
복사
Add the following to your app's build.gradle.
dependencies {
implementation 'io.channel:plugin-android:$[version]'
// Used to setup FCM easily
implementation 'io.channel:plugin-android-fcm:$[version]'
}
Groovy
복사
If you are using Proguard, add the following to your proguard configuration.
-keep class com.zoyi.**{ *; }
-keep class io.channel.**{ *; }
-dontwarn com.zoyi.**
-dontwarn io.channel.**
Plain Text
복사
If an error related to Multidex occurs, you need to set up Multidex.
android {
defaultConfig {
...
multiDexEnabled true
}
}
Groovy
복사
Step 2. Initialize ChannelIO
Initialize ChannelIO in onCreate of FlutterApplication.
class App: FlutterApplication() {
...
override fun onCreate() {
super.onCreate()
ChannelIO.initialize(this)
}
...
}
Kotlin
복사
Step 3. Using ChannelIO
Below is a simple example of using ChannelIO SDK.
For more information on how to use ChannelIO, please check the link.
•
Flutter(Dart)
// ChannelIO.dart
import 'dart:async';
import 'package:flutter/services.dart';
class ChannelIO {
static const platform = const MethodChannel("com.example.SampleProject/channelIO");
static const badgeChannel = const EventChannel("com.example.SampleProject/channelIO/badge");
static Future<String> boot() async {
return platform.invokeMethod("boot", {
"bootConfig" : {
"pluginKey" : PLUGIN_KEY,
"memberId" : "flutter-test",
},
});
}
static void sleep() {
platform.invokeMethod("sleep");
}
static void shutdown() {
platform.invokeMethod("shutdown");
}
static void showChannelButton() {
platform.invokeMethod("showChannelButton");
}
static void showMessenger() {
platform.invokeMethod("showMessenger");
}
static void track(String eventName) {
platform.invokeMethod("track", eventName);
}
static void setBadgeListener(Function listener) {
badgeChannel.receiveBroadcastStream().listen((badgeCount) {
listener.call(badgeCount);
});
}
}
Dart
복사
// ChannelIOSamplePage
class ChannelIOSamplePage extends StatefulWidget {
...
}
class _ChannelIOSamplePageState extends State<ChannelIOSamplePage> {
...
void _boot() async {
ChannelIO.boot().then((bootStatus) => {
...
});
ChannelIO.setBadgeListener((badge) => {
...
});
}
void _sleep() {
ChannelIO.sleep();
}
void _shutdown() {
ChannelIO.shutdown();
}
void _showMessenger() {
ChannelIO.showMessenger();
}
void _showChannelButton() {
ChannelIO.showChannelButton();
}
void _track() {
ChannelIO.track("flutter_event");
}
...
}
Dart
복사
•
Android(Kotlin)
// MainActivity
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
val manager = ChannelIOManager()
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
ChannelIOManager.CHANNEL_CHANNELIO
).setMethodCallHandler { call, result ->
when (call.method) {
"boot" -> manager.boot(
call.argument<HashMap<String, Any?>>("bootConfig"),
result
)
"sleep" -> manager.sleep()
"shutdown" -> manager.shutdown()
"showChannelButton" -> manager.showChannelButton()
"showMessenger" -> manager.showMessenger(this)
"track" -> manager.track(call.arguments<String>())
}
}
EventChannel(
flutterEngine.dartExecutor.binaryMessenger,
ChannelIOManager.CHANNEL_BADGE_EVENT
).setStreamHandler(object : StreamHandler {
override fun onListen(arguments: Any?, events: EventSink?) {
manager.setBadgeListener(events)
}
override fun onCancel(arguments: Any?) {
}
})
}
...
}
Kotlin
복사
// ChannelIOManager
class ChannelIOManager : ChannelPluginListener {
private var eventSink: EventSink? = null
fun boot(bootConfig: HashMap<String, Any?>?, result: MethodChannel.Result) {
ChannelIO.setListener(this)
val config: BootConfig? = BootConfig.fromJson(Gson().toJson(bootConfig))
ChannelIO.boot(config) { bootStatus: BootStatus, user: User? ->
result.success(bootStatus.toValue())
}
}
fun sleep() {
ChannelIO.sleep()
}
fun shutdown() {
ChannelIO.shutdown()
}
fun showChannelButton() {
ChannelIO.showChannelButton()
}
fun showMessenger(activity: Activity) {
ChannelIO.showMessenger(activity)
}
fun track(eventName: String?) {
eventName?.also { ChannelIO.track(it) }
}
fun setBadgeListener(eventSink: EventSink?) {
this.eventSink = eventSink
}
...
override fun onBadgeChanged(count: Int) {
this.eventSink?.success(count)
}
...
companion object {
const val CHANNEL_CHANNELIO = "com.example.SmapleProject/channelIO"
const val CHANNEL_BADGE_EVENT = "com.example.SmapleProject/channelIO/badge"
}
}
Kotlin
복사
Push Notification
ChannelIO's Android SDK sends and receives messages through FCM.
There are various settings depending on how you use FCM, but this guide shows you the most basic settings.
•
Flutter(Dart)
class ChannelIO {
...
static void openStoredPushNotification() {
platform.invokeMethod("openStoredPushNotification");
}
...
}
Dart
복사
// ChannelIOSamplePage
class ChannelIOSamplePage : FlutterActivity() {
...
}
class _ChannelIOSamplePageState extends State<ChannelIOSamplePage> {
...
void initState() {
super.initState();
ChannelIO.openStoredPushNotification()
}
...
}
Dart
복사
•
Android(Kotlin)
// FCMService
class FCMService: FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
ChannelIO.initPushToken(token)
...
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
val pushMessage: Map<String, String> = remoteMessage.data
if (ChannelIO.isChannelPushNotification(pushMessage)) {
ChannelIO.receivePushNotification(application, pushMessage)
} else {
// Enter your code
}
}
}
Kotlin
복사
class ChannelIOManager : ChannelPluginListener {
...
fun openStoredPushNotification(activity: Activity) {
if (ChannelIO.hasStoredPushNotification()) {
ChannelIO.openStoredPushNotification(activity)
}
}
...
}
Kotlin
복사
iOS
Installation
It's basically the same as native, and I used CocoaPods in this guide.
Depending on the Xcode version and CocoaPods version, the setting method may be different.
Step 1. Dependencies installation
# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'
target 'Runner' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for Runner
...
pod 'ChannelIOSDK', podspec: 'https://mobile-static.channel.io/ios/latest/xcframework.podspec'
...
end
Plain Text
복사
After that, install it through pod install.
Step 2. Initialize ChannelIO
Initialize ChannelIO in AppDelegate
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
...
ChannelIO.initialize(application)
...
}
Swift
복사
Step 3. Using ChannelIO
Below is a simple example of using ChannelIO SDK.
For more information on how to use ChannelIO, please check the link.
•
Flutter(Dart)
// ChannelIO.dart
import 'dart:async';
import 'package:flutter/services.dart';
class ChannelIO {
static const platform = const MethodChannel("com.example.SampleProject/channelIO");
static const badgeChannel = const EventChannel("com.example.SampleProject/channelIO/badge");
static Future<String> boot() async {
return platform.invokeMethod("boot", {
"bootConfig" : {
"pluginKey" : PLUGIN_KEY,
"memberId" : "flutter-test",
},
});
}
static void sleep() {
platform.invokeMethod("sleep");
}
static void shutdown() {
platform.invokeMethod("shutdown");
}
static void showChannelButton() {
platform.invokeMethod("showChannelButton");
}
static void showMessenger() {
platform.invokeMethod("showMessenger");
}
static void track(String eventName) {
platform.invokeMethod("track", eventName);
}
static void setBadgeListener(Function listener) {
badgeChannel.receiveBroadcastStream().listen((badgeCount) {
listener.call(badgeCount);
});
}
}
Dart
복사
// ChannelIOSamplePage
class ChannelIOSamplePage extends StatefulWidget {
...
}
class _ChannelIOSamplePageState extends State<ChannelIOSamplePage> {
...
void _boot() async {
ChannelIO.boot().then((bootStatus) => {
...
});
ChannelIO.setBadgeListener((badge) => {
...
});
}
void _sleep() {
ChannelIO.sleep();
}
void _shutdown() {
ChannelIO.shutdown();
}
void _showMessenger() {
ChannelIO.showMessenger();
}
void _showChannelButton() {
ChannelIO.showChannelButton();
}
void _track() {
ChannelIO.track("flutter_event");
}
...
}
Kotlin
복사
•
iOS(Swift)
// AppDelegate
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
ChannelIO.initialize(application)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
FlutterMethodChannel(
name: ChannelIOManager.CHANNEL_CHANNELIO,
binaryMessenger: controller.binaryMessenger
).setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
switch call.method {
case "boot": ChannelIOManager.shared.boot(
bootConfig: (call.arguments as? [String:Any?])?["bootConfig"] as? [String:Any?],
result: result
)
case "sleep": ChannelIOManager.shared.sleep()
case "shutdown": ChannelIOManager.shared.shutdown()
case "showChannelButton": ChannelIOManager.shared.showChannelButton()
case "showMessenger": ChannelIOManager.shared.showMessenger()
case "track": ChannelIOManager.shared.track(eventName: call.arguments as? String)
default: break
}
}
let handler = BadgeHandler()
FlutterEventChannel(
name: ChannelIOManager.CHANNEL_BADGE_EVENT,
binaryMessenger: controller.binaryMessenger
).setStreamHandler(handler)
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Swift
복사
// BadgeHandler
class BadgeHandler: NSObject, FlutterStreamHandler {
func onListen(
withArguments arguments: Any?,
eventSink events: @escaping FlutterEventSink
) -> FlutterError? {
ChannelIOManager.shared.setBadgeListener(events)
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
return nil
}
}
Swift
복사
// ChannelIOManager
class ChannelIOManager {
static let CHANNEL_CHANNELIO = "com.example.SmapleProject/channelIO"
static let CHANNEL_BADGE_EVENT = "com.example.SmapleProject/channelIO/badge"
static let shared: ChannelIOManager = ChannelIOManager()
private var eventSink: FlutterEventSink?
func boot(bootConfig: [String:Any?]?, result: @escaping FlutterResult) {
ChannelIO.delegate = self
let config: BootConfig = BootConfig()
config.pluginKey = bootConfig?["pluginKey"] as? String ?? ""
config.memberId = bootConfig?["memberId"] as? String
ChannelIO.boot(with: config) { bootStatus, user in
result(bootStatus == .success ? "SUCCESS" : "ERROR")
}
}
func sleep() {
ChannelIO.sleep()
}
func shutdown() {
ChannelIO.shutdown()
}
func showChannelButton() {
ChannelIO.showChannelButton()
}
func showMessenger() {
ChannelIO.showMessenger()
}
func track(eventName: String?) {
guard let eventName = eventName else { return }
ChannelIO.track(eventName: eventName)
}
func setBadgeListener(_ eventSink: FlutterEventSink?) {
self.eventSink = eventSink
}
func openStoredPushNotification() {
if ChannelIO.hasStoredPushNotification() {
ChannelIO.openStoredPushNotification()
}
}
}
extension ChannelIOManager: ChannelPluginDelegate {
func onBadgeChanged(count: Int) {
guard let eventSink = self.eventSink else { return }
eventSink(count)
}
}
Swift
복사
Push Notification
ChannelIO's iOS SDK sends and receives messages through APNS.
There are various settings depending on how you use APNS, but this guide shows the most basic settings.
For more detailed usage, please refer to Link.
•
Flutter(Dart)
class ChannelIO {
...
static void openStoredPushNotification() {
platform.invokeMethod("openStoredPushNotification");
}
...
}
Dart
복사
// ChannelIOSamplePage
class ChannelIOSamplePage : FlutterActivity() {
...
}
class _ChannelIOSamplePageState extends State<ChannelIOSamplePage> {
...
void initState() {
super.initState();
ChannelIO.openStoredPushNotification()
}
...
}
Dart
복사
•
iOS(Swift)
class AppDelegate {
...
override func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
ChannelIO.initPushToken(deviceToken: deviceToken)
}
@available(iOS 10.0, *)
override func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
if ChannelIO.isChannelPushNotification(userInfo) {
ChannelIO.receivePushNotification(userInfo)
ChannelIO.storePushNotification(userInfo)
}
completionHandler()
}
...
}
Swift
복사
class ChannelIOManager {
...
func openStoredPushNotification() {
if ChannelIO.hasStoredPushNotification() {
ChannelIO.openStoredPushNotification()
}
}
...
}
Swift
복사