dim 0.2.6

dim #

封装的一个腾讯云im,以便于flutter开发者可以方便继承im到自己的应用中

使用之前注意事项 #

如果你之前没有使用过腾讯云,请仔细阅读这段文字,如果你已经对腾讯云im了如指掌,可以越过,但建议还是熟悉以下。

因为这个库是基于腾讯云im的,因此需要去云im申请一个应用,阅读这篇文章可以获得以下知识:

1、appid怎么来的

2、账号及其对应的sig如何来的,已经推荐的sig的生成方式(当然这个是后台同学关注的)。

弄清楚这些之后,就可以开始使用dim了。

使用 dim #

dim的使用非常简单,只需引入这个库就可以使用了。

dependencies:
  dim: ^0.2.6

不需要像我之前实现的版本那样进行一些繁琐的配置,因为云im升级之后,支持maven以及pod的引用方式啦。那么Android端

Android端需要注意什么? #

1、混淆配置,在你的flutter的Android工程中配置混淆。

-keep class com.tencent.** { *; }

IOS端需要注意什么? #

1、请注意在你的flutter工程的ios项目根目录执行pod update[非必须,如果报错建议执行一次]

2、随后在执行一次pod install

demo截图 #

截图

构建

已有的功能 #

  1. 初始化

    建议整个应用生命周期只执行一次。

  2. 登录

  3. 登出

  4. 获取会话列表

  5. 删除一个会话

  6. 获取私信会话消息[群聊消息目前没有封装]

    注意,私信发送方的资料云im改成了异步的方式,因此,这个版本不在返回! 建议用户自己查询一次,最好的方式是将用户资料存储在本地db中,并

  7. 发送图片消息

    注意,图片消息中图片云im需要的是图片的本地路径

  8. 发送文本消息

  9. 发送地理位置消息

  10. 获取用户资料

  11. 设置用户资料

    目前仅仅提供了设置nickgenderfaceUrl,有需要在补充。

  12. 监听新的消息

  13. 监听有新的会话

    注意,和新的消息是一个消息通道,只不过收到的内容是`[]`,对一个空的数组,此时需要去主动调用4获取会话列表来查最新会话列表
    
  14. 发送语音消息,基本和图片消息一致,使用本地路径

todo #

根据需要,可以提issue,或者接受pr来实现更多的接口,主要是体力活。

0.2.6 #

可以发送语音消息

0.2.5 #

增加新的会话监听

0.2.4 #

简化描述

0.2.3 #

迁移仓库

0.2.2 #

修改一些说明文件。

0.2.1 #

修改不支持的引用头文件的方式。

0.2.0 #

升级imsdk到官方最新版本。

0.1.19 #

获取用户个人资料

0.1.16 #

简化dim的使用,android端不在需要在AndroidManifests.xml文件中配置service等内容,全部交给插件处理。

0.1.13 #

  • 归一化错误码

0.1.11 #

  • 去掉无用api,解决消息重复的问题,定位到是重复登录注册了多次listener,做了容错处理。

0.1.8 #

  • 解决了消息解析不出的问题。

example/lib/main.dart

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

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

import 'dart:math';

void main() => runApp(new MyApp());

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

class _MyAppState extends State<MyApp> {
  Dim _dim = new Dim();

  String _result = "";

  List<dynamic> _users = List();

  //在另外一个手机上测试改变下用户,靠这里了
  int _currentUser = 1;

  int appid = 1400215656;

  StreamSubscription<dynamic> _messageStreamSubscription;

  @override
  void initState() {
    super.initState();
    initPlatformState();
    _users.add({
      'username': 'hoolly1',
      'sig':
          "eJxlj8FPgzAche-8FYTrjLbQgngbbkEmHIgzZF4Iwg*obLTSssmM-7sRNTbxXb8v7*W9G6ZpWtv44bIoSz72KleTAMu8MS1kXfxBIViVFyp3huofhDfBBsiLWsEwQ0wptRHSHVZBr1jNfoyW8-1*wpogqy6fV74bCEI2pi51dYU1M0zWu9soXWUp37Q0CKYoCGJVPi3ASRkbty*CyCQeC7dZc1igFK5OUbvchMdyyvz7tqulF3qrJT3Is-vYvI4nz92hwc-EHQnpM0k6bVKxA-xe8sk19oij0SMMkvF*FmyEKbYd9BXL*DA*AfzTXb0_"
    });
    _users.add({
      'username': 'hoolly2',
      'sig':
          "eJxlj8FOg0AURfd8BWFbIzMDM60mLhqUhNpqacUFGwKdgb4yDATGltb470bUSOLbnpN773s3TNO0Xpbb63S3q9*UTvS5EZZ5a1rIuvqDTQM8SXXitPwfFH0DrUjSXIt2gJhSShAaO8CF0pDDj7GvaynPZCR0vEyGlu8EFyGCKaNsrEAxwNVD5AXhPeHk4D1uTq7wudL9pVB9PJmjCmTZ*pn0Q8*3N9sc8qciKBbsGOBYnEo2E5nM9yxmr5FcVwd7MWEdrHHozLPnVbS0w7tRpYZK-L50487wdDrefBRtB7UaBIIwxcRBX2cZH8YnH3NdyQ__"
    });
    _users.add({
      'username': 'hoolly3',
      'sig':
          "eJxlj11PgzAARd-5FU2fjbZA2ccbwW0QYbqMEeSlAdpB2YQGyiYx-ncjakbifT0n9*Z*aAAAGPr7*zTPm75WVA2SQ7AEEMG7G5RSMJoqarTsH*TvUrScpkfF2xFiQoiO0NQRjNdKHMWvUTbN*TwYE6FjJzqu-DSYCOmYWMSaKqIYYbB6dbyd40XeY6i8uHpyS5*blzBKtv1zvtrGa9Zd1yeLWb0hrzxyba*0g83eVpsgr5wC6Vl8KHYvWZUmTvdQJ2o4ZHXH0eD77tywJ5NKvPG-SwtzjmeL2YReeNuJph4FHWGCdQN9B2qf2hc3HF5a"
    });
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      platformVersion = await _dim.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    if (_messageStreamSubscription == null) {
      _messageStreamSubscription = _dim.onMessage.listen((dynamic onData) {
        print(
            "我监听到数据了$onData,需要在这里判断是你是消息列表还是需要刷新会话的请求。会话的请求是一个空的列表[],消息列表是有内容的");
      });
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    //flutter 这里应该页面退出栈会调用,但是如果这个是根页面,日志是打不出来的。
    canCelListener();
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: Text('当前账号' + _users[_currentUser]["username"]),
        ),
        body: new Center(
          child: CustomScrollView(
            primary: false,
            slivers: <Widget>[
              SliverPersistentHeader(
                delegate: _SliverAppBarDelegate(
                    minHeight: 30,
                    maxHeight: 200,
                    child: Container(
                      margin: EdgeInsets.all(10),
                      padding: EdgeInsets.all(4),
                      decoration: BoxDecoration(
                          border: Border.all(),
                          borderRadius: BorderRadius.all(Radius.circular(5))),
                      child: SingleChildScrollView(
                        child: Text(_result.isEmpty ? "这里显示输出结果" : _result),
                      ),
                    )),
                pinned: true,
              ),
              SliverPadding(
                padding: const EdgeInsets.all(10.0),
                sliver: SliverGrid.count(
                  crossAxisSpacing: 10.0,
                  mainAxisSpacing: 10.0,
                  crossAxisCount: 4,
                  children: <Widget>[
                    RaisedButton(
                      onPressed: () {
                        init();
                      },
                      child: Text('初始化'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        login();
                      },
                      child: Text('登录'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        logout();
                      },
                      child: Text('登出'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        postData();
                      },
                      child: Text('测试发送数据'),
                    ),
//                    RaisedButton(
//                      onPressed: () {
//                        canCelListener();
//                      },
//                      child: Text('取消监听'),
//                    ),
                    RaisedButton(
                      onPressed: () {
                        sendTextMsg();
                      },
                      child: Text('发文本'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        sendImageMsg();
                      },
                      child: Text('发图片'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        sendLocationMsg();
                      },
                      child: Text('发位置'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        getMessages();
                      },
                      padding: EdgeInsets.all(0),
                      child: Text('历史消息'),
                    ),
                    RaisedButton(
                      onPressed: () {
                        getUserInfo();
                      },
                      child: Text('拿资料'),
                    ),
                    RaisedButton(
                      padding: EdgeInsets.all(0),
                      onPressed: () {
                        setUserInfo();
                      },
                      child: Text('设置资料'),
                    ),
                    RaisedButton(
                      padding: EdgeInsets.all(0),
                      onPressed: () {
                        getConversations();
                      },
                      child: Text('会话列表'),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> postData() async {
    try {
      var result = await _dim.postDataTest();
      setState(() {
        this._result = result;
      });
      print(result);
    } on PlatformException {
      print("listen  失败");
    }
  }

  Future<void> sendTextMsg() async {
    try {
      var result = await _dim.sendTextMessages(
          _users[_users.length - _currentUser - 1]['username'], "haahah");
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("发送消息失败");
      setState(() {
        this._result = "发送消息失败";
      });
    }
  }

  Future<void> sendImageMsg() async {
    try {
      var result = await _dim.sendImageMessages(
          _users[_users.length - _currentUser - 1]['username'],
          "tyyhuiijkoi.png");
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("发送图片消息失败");
      setState(() {
        this._result = "发送图片消息失败";
      });
    }
  }

  Future<void> sendLocationMsg() async {
    try {
      var result = await _dim.sendLocationMessages(
          _users[_users.length - _currentUser - 1]['username'],
          113.93,
          22.54,
          "腾讯大厦");
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("发送位置消息失败");
      setState(() {
        this._result = "发送位置消息失败";
      });
    }
  }

  ///测试化测试,这里传自己应用的appid
  Future<void> init() async {
    try {
      var result = await _dim.init(appid);
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("初始化失败");
    }
  }

  ///第一个测试账号
  Future<void> login() async {
    try {
      var result = await _dim.imLogin(
          _users[_currentUser]['username'], _users[_currentUser]['sig']);
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("登录  失败");
    }
  }

  Future<void> logout() async {
    try {
      var result = await _dim.imLogout();
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("登出  失败");
    }
  }

  Future<dynamic> getMessages() async {
    try {
      var result = await _dim.getMessages(
        _users[_users.length - _currentUser - 1]['username'],
      );
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {}
  }

  void canCelListener() {
    if (_messageStreamSubscription != null) {
      _messageStreamSubscription.cancel();
    }
  }

  void getUserInfo() async {
    try {
      List<String> users = List();
      users.add(_users[_users.length - _currentUser - 1]['username']);
      var result = await _dim.getUsersProfile(users);
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("获取个人资料失败");
    }
  }

  void setUserInfo() async {
    try {
      var result = await _dim.setUsersProfile(
          1, "hz", "https://www.brzhang.club/images/hz.png");
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("获取个人资料失败");
    }
  }

  void getConversations() async {
    try {
      var result = await _dim.getConversations();
      print(result);
      setState(() {
        this._result = result;
      });
    } on PlatformException {
      print("获取会话列表失败");
    }
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.child,
  });

  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => max(maxHeight, minHeight);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return new SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dim: ^0.2.6

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dim/dim.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
60
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
80
Learn more about scoring.

We analyzed this package on Sep 20, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.0
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.2

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.7
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8