Flutter TDJSON通信插件libtdjson的使用

Flutter TDJSON通信插件libtdjson的使用

简介

flutter_libtdjson 是一个用于在 Flutter 应用中使用 TDLib JSON 接口的插件。该插件提供了 FFI 绑定,使开发者能够通过 Flutter 调用 TDLib 的功能。

版本信息

以下是 flutter_libtdjson 支持的不同版本及其对应的 TDLib 版本:

package td version
0.2.1 1.8.31 (Android, iOS, macOS)
0.2.0 1.8.30 (Android, iOS, macOS)
0.1.4 1.8.1 (Android, iOS, macOS)
0.1.3 1.7.9 (Android, iOS, macOS)
0.1.2 1.7.0 (Android), latest (iOS, macOS)

支持的架构

请确保你使用的架构是支持的:

Platform Architecture Status
Android armeabi-v7a
arm64-v8a
Android Emulator x86
x86_64
iOS armv7
armv7s
arm64
iOS Simulator i386
x86_64
arm64 (M1)
macOS i386
x86_64
arm64 (M1)

安装

要使用 flutter_libtdjson 插件,请按照以下步骤进行安装:

  1. 更新 pubspec.yaml 文件

    dependencies:
      libtdjson: ^0.2.1
    
  2. 如果要构建 Android 版本,需要添加 GitHub Maven 环境变量:

    export GITHUB_ACTOR=<username>
    export GITHUB_TOKEN=<personal access token>
    
  3. 如果要设置 tdlibParameters.database_directory 外部工作目录,请确保请求存储权限(例如在 android/app/src/main/AndroidManifest.xml 中):

    <manifest>
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    </manifest>
    
  4. 如果要构建 macOS 版本,需要在 ./macos/Runner/*.entitlements 文件中设置网络权限:

    <dict>
        <key>com.apple.security.network.client</key>
        <true/>
    </dict>
    

示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 flutter_libtdjson 插件:

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart' show GetIt;
import 'package:global_configuration/global_configuration.dart';

import './service/mod.dart' show registerAll, NavigationService;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await GlobalConfiguration().loadFromAsset("app");
  registerAll();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: GetIt.I<NavigationService>().navigatorKey,
      title: 'Flutter Demo',
      theme: ThemeData.dark(),
      onGenerateRoute: NavigationService.onGenerateRoute,
    );
  }
}

开发注意事项

升级 TDLib 版本

  1. 更新 android-libtdjson 的 TDLib 版本。

  2. ./android/build.gradle 中更新 Android 依赖版本。

  3. 对于 Android 平台,运行以下命令:

    cd ./example
    flutter run -d emulator-5554
    
  4. 更新 ios-libtdjson 的 TDLib 版本。

  5. ./macos/libtdjson.podspec 中更新 macOS 依赖版本(s.dependency)。

  6. 对于 macOS 平台,运行以下命令:

    cd ./example/macos
    pod update flutter_libtdjson
    cd ..
    flutter run -d macos
    
  7. 更新 ios-libtdjson 的 iOS 依赖版本。

  8. 对于 iOS 模拟器,运行以下命令:

    cd ./example/ios
    pod update flutter_libtdjson
    cd ..
    flutter run --debug
    # 链接 .dylib 到搜索路径,例如:
    # ln -s $(pwd)/build/ios/Debug-iphonesimulator/XCFrameworkIntermediates/flutter_libtdjson/libtdjson.dylib ~/Library/Developer/CoreSimulator/Devices/FD63D560-544B-4B18-8F2F-03B093156DE2/data/Containers/Bundle/Application/004B7B3D-4665-4217-A9C7-2D2193107E80/Runner.app/Frameworks/libtdjson.dylib
    # 重新加载使用 `R`
    
  9. 更新 ./pubspec.yaml 中的包版本。

  10. ./CHANGELOG.md 中添加新版本的变更日志。

  11. 更新 ./README.md 中的版本信息。

  12. 提交 Git 代码(提交信息示例:bump td to vx.x.x)。

  13. 添加 Git 标签(git tag v?.?.?,标签版本应与 pubspec.yaml 中的版本相同)。

  14. 推送代码及标签(git push && git push --tags)。

  15. 等待 CI 任务完成。

手动发布

请参考 Dart 文档 进行手动发布:

dart pub publish

# 凭证文件在 macOS 上的位置
cat ~/Library/Application Support/dart/pub-credentials.json

更多关于Flutter TDJSON通信插件libtdjson的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter TDJSON通信插件libtdjson的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter中使用libtdjson(Telegram Database JSON接口库)进行TDJSON通信,以下是一个基本的代码案例来展示如何集成和使用这个插件。请注意,由于libtdjson本身是一个C库,所以在Flutter中使用它通常涉及到平台通道(Platform Channels)或者一些现有的Flutter插件(如果可用)。

假设你已经有一个Flutter项目,并且想要集成libtdjson,以下是一个基本的步骤和代码示例:

1. 添加原生依赖

首先,你需要在iOS和Android项目中添加libtdjson的依赖。

iOS

在你的ios/Podfile中添加对libtdjson的依赖(注意:libtdjson可能不是通过CocoaPods直接可用的,这里假设有一个pod可用或者你需要手动集成):

platform :ios, '10.0'

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

  # 添加libtdjson依赖(如果可用)
  pod 'TDLib', :path => '../path/to/tdlib/ios'  # 替换为实际的路径或spec
end

如果libtdjson不是通过CocoaPods管理的,你可能需要手动下载并集成到Xcode项目中。

Android

在你的android/build.gradle文件中添加对libtdjson的依赖(同样,这里假设有一个可用的依赖,否则你需要手动集成):

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }  // 如果libtdjson在jitpack上可用
    }
}

android/app/build.gradle中添加:

dependencies {
    implementation 'com.github.YourUsername:libtdjson:TagOrVersion'  // 替换为实际的依赖信息
}

如果libtdjson没有预构建的Android库,你可能需要下载源代码并构建它,然后将生成的.aar文件或.so文件集成到你的项目中。

2. 创建平台通道

接下来,在Flutter中创建一个平台通道来与原生代码通信。

Flutter代码

lib目录下创建一个新的Dart文件,比如tdjson_channel.dart

import 'dart:async';
import 'package:flutter/services.dart';

class TdJsonChannel {
  static const MethodChannel _channel = const MethodChannel('tdjson_channel');

  static Future<String?> sendMessage(String message) async {
    final String? result = await _channel.invokeMethod('sendMessage', message);
    return result;
  }

  static Future<void> setTdlibParameters(Map<String, dynamic> parameters) async {
    await _channel.invokeMethod('setTdlibParameters', parameters);
  }

  static Future<Stream<dynamic>> listenToUpdates() async {
    return _channel.receiveBroadcastStream();
  }
}

原生代码(iOS)

ios/Runner/AppDelegate.swift或创建一个新的Swift文件来处理平台通道:

import UIKit
import Flutter
import YourTdlibModule  // 替换为实际的模块名

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    
    let controller = Window.rootViewController! as! FlutterViewController
    let channel = FlutterMethodChannel(name: "tdjson_channel", binaryMessenger: controller.binaryMessenger)
    
    channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
      switch call.method {
      case "sendMessage":
        if let message = call.arguments as? String {
          // 在这里调用TDLib的API发送消息
          // 例如: YourTdlibModule.sendMessage(message)
          result("Message sent")
        } else {
          result(FlutterError(code: "INVALID_ARGUMENT", message: "Message argument is missing", details: nil))
        }
      case "setTdlibParameters":
        if let parameters = call.arguments as? [String: Any] {
          // 设置TDLib参数
          // 例如: YourTdlibModule.setParameters(parameters)
          result(())
        } else {
          result(FlutterError(code: "INVALID_ARGUMENT", message: "Parameters argument is missing", details: nil))
        }
      default:
        result(FlutterMethodNotImplemented)
      }
    }
    
    // 监听TDLib更新并通过平台通道发送回Flutter
    // 例如: YourTdlibModule.addListener { update in
    //   channel.invokeMethod("sendUpdate", update)
    // }
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

原生代码(Android)

android/app/src/main/kotlin/.../MainActivity.kt(或Java文件)中添加平台通道处理:

package com.example.yourapp

import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import your.tdlib.module.TdlibModule  // 替换为实际的模块名

class MainActivity: FlutterActivity() {
    private val CHANNEL = "tdjson_channel"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "sendMessage" -> {
                    val message = call.argument<String>("message") ?: run {
                        result.error("INVALID_ARGUMENT", "Message argument is missing", null)
                        return@setMethodCallHandler
                    }
                    // 在这里调用TDLib的API发送消息
                    // 例如: TdlibModule.sendMessage(message)
                    result.success("Message sent")
                }
                "setTdlibParameters" -> {
                    val parameters = call.argument<Map<String, Any>>("parameters") ?: run {
                        result.error("INVALID_ARGUMENT", "Parameters argument is missing", null)
                        return@setMethodCallHandler
                    }
                    // 设置TDLib参数
                    // 例如: TdlibModule.setParameters(parameters)
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }

        // 监听TDLib更新并通过平台通道发送回Flutter
        // 例如: TdlibModule.addListener { update ->
        //   MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).invokeMethod("sendUpdate", update)
        // }
    }
}

3. 使用插件

现在你可以在Flutter代码中使用这个插件了:

import 'package:flutter/material.dart';
import 'tdjson_channel.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  StreamSubscription<dynamic>? _tdlibUpdatesSubscription;

  @override
  void initState() {
    super.initState();
    // 设置TDLib参数
    TdJsonChannel.setTdlibParameters({
      'parameter1': 'value1',
      'parameter2': 'value2',
    });

    // 监听TDLib更新
    _tdlibUpdatesSubscription = TdJsonChannel.listenToUpdates().listen((update) {
      // 处理TDLib更新
      print('TDLib update: $update');
    });

    // 发送消息
    TdJsonChannel.sendMessage('Hello, TDLib!').then((response) {
      print('Message sent response: $response');
    });
  }

  @override
  void dispose() {
    _tdlibUpdatesSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter TDJSON Demo'),
        ),
        body: Center(
          child: Text('Waiting for TDLib updates...'),
        ),
      ),
    );
  }
}

注意

  1. 上述代码是一个简化的示例,用于展示如何在Flutter中设置平台通道并与原生代码通信。
回到顶部