wilddog_sync 0.0.6

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 68

Flutter插件一野狗云实时通信

pub package

使用野狗实时通信引擎(Wilddog Sync)的Flutter插件。野狗实时通信引擎即Sync,可以帮助开发者解决应用的实时通信问题,开发者通过API,即可为应用建立客户端之间的长连接,并实时地双向同步数据。

开发者使用Sync能快速实现三大功能:实时数据通信、实时数据分发以及实时数据存储,以下介绍Sync常见的应用场景。

  • 实时聊天:可用于直播或社交应用中的实时聊天,完成消息同步、房间信息存储、在线状态检测等功能。
  • 实时协作:适用于多人在线文档协同编辑,资料实时同步、在线问答、需求沟通、项目管理等场景。
  • 实时金融:适用金融服务中大量的 Sync 业务、包括股票行情、实盘演示;期货、黄金、债券、证券等金融领域的实时新闻推送。
  • 实时定位:结合 GPS 数据,可以应用于外卖配送、物流定位等互动场景;也可应用于打车应用中的司机、乘客实时定位;社交应用中,最常见的场景就是:分享我的位置。

注意:此插件还不是很完善,有些功能仍在开发中,如果你发现任何问题,请加入QQ群:271733776【Flutter程序员】,期待你的反馈。

安装与配置

打开野狗云官网,注册一个野狗云帐号,已有账号的直接登陆。

创建一个新Wilddog项目

在Flutter项目上配置Wilddog Sync的第一步是创建一个新的Wilddog项目,在浏览器中打开Wilddog控制台,选择“创建应用”,输入项目名称,然后单击“创建”。

这里写图片描述

Wilddog生成了一个App ID的字符串,这是Wilddog项目唯一ID,用于连接到刚创建的Wilddog服务。复制这个ID字符串值,下面在Android、iOS平台上配置Wilddog时需要用到这个值。

注意,新项目需要开启实时通信引擎服务才能正常使用,不然会报无权限异常。

将插件添加到应用程序

将以下内容添加到的Flutter项目的pubspec.yaml文件中。

dependencies:
  wilddog_sync: "^0.0.4"

更新并保存此文件后,点击顶部的“Packages Get”,等待下载完成。打开main.dart文件,IntelliJ IDEA或其他编辑器可能会在上方显示一个提示,提醒我们重新加载pubspec.yaml文件,点击“Get dependencies”以检索其他软件包,并在Flutter项目中使用它们。

开发iOS必须使用macOS,而在macOS中,想要在Flutter应用程序中使用Flutter插件,需要安装homebrew,并打开终端运行以下命令来安装CocoaPods。

brew install cocoapods
pod setup

为Android配置Wilddog

启动Android Studio后选择项目的android文件夹,打开Flutter项目的Android部分,然后再打开“android/app/src/main/java/<项目名>”文件夹中的MainActivity.java文件,将Wilddog的初始化代码添加到文件中。

//...
import com.wilddog.wilddogcore.WilddogOptions;
import com.wilddog.wilddogcore.WilddogApp;

public class MainActivity extends FlutterActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    //...
    WilddogOptions options = new WilddogOptions.Builder().setSyncUrl("https://<前面复制的AppID>.wilddogio.com/").build();
    WilddogApp.initializeApp(this, options);
  }
}

注意,如果应用程序编译时出现文件重复导致的编译错误时,可以选择在android/app/build.gradle中添加“packagingOptions”。

android {
    //...
    packagingOptions {
        exclude 'META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
        exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
        exclude 'META-INF/maven/com.squareup.okhttp/okhttp/pom.properties'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.xml'
        exclude 'META-INF/maven/com.squareup.okio/okio/pom.properties'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.xml'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.properties'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.properties'
        exclude 'META-INF/maven/com.squareup.okio/okio/pom.xml'
        exclude 'META-INF/maven/com.squareup.okhttp/okhttp/pom.xml'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.properties'
        exclude 'META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.xml'
        exclude 'META-INF/maven/com.wilddog.client/wilddog-core-android/pom.xml'
        exclude 'META-INF/maven/com.wilddog.client/wilddog-core-android/pom.properties'
        exclude 'META-INF/maven/com.wilddog.client/wilddog-auth-android/pom.xml'
        exclude 'META-INF/maven/com.wilddog.client/wilddog-auth-android/pom.properties'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/notice'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license'
        exclude 'META-INF/license.txt'
    }
}

完成配置后,建议先在IntelliJ IDEA中执行一次项目,编译Android应用程序,以确保Flutter项目下载所有依赖文件。

为iOS配置Wilddog

在Flutter项目的ios目录下,使用Xcode打开“Runner.xcworkspace”文件。然后打开“ios/Runner”文件夹中的AppDelegate.m文件,将Wilddog的初始化代码添加到文件中。

//...
#import "Wilddog.h"
//...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  //...
  WDGOptions *option = [[WDGOptions alloc] initWithSyncURL:@"https://<前面复制的AppID>.wilddogio.com/"];
  [WDGApp configureWithOptions:option];
  //...
}

完成配置后,建议先在IntelliJ IDEA中执行一次项目,编译iOS应用程序,以确保Flutter项目下载所有依赖文件。

使用与入门

要使用Flutter的平台插件,必须在Dart代码中导入对应包,使用以下代码导入wilddog_sync包。

import 'package:wilddog_sync/wilddog_sync.dart';

基础概念

Sync的数据以JSON格式存储,它是键值对(Key-Value)的集合,其中每一个键值对(Key-Value)都称之为节点。一个节点包含keyvalue ,例如,以下聊天室示例的数据结构中,“name”是key,“username1”是“name”对应的value,它们共同组成一个节点。

这里写图片描述

某个节点下的所有节点,统称为该节点的子节点,例如,聊天室示例中“user1”是“users”的子节点。路径用于标识数据在Sync中存储的位置,根据路径可以访问指定的数据,例如,聊天室示例中“name”的路径是“users/user1/name”。

写入数据

使用WilddogSync.instance.reference()会获取一个指向根节点的SyncReference实例,child方法用来定位到某个子节点。

使用set方法可以向指定节点写入数据,此方法会先清空指定节点,再写入数据。通过设置priority参数可以节点的优先级,默认值为“0”。

如果子节点的value是列表时,可以使用push方法。push方法使用唯一key生成新的子节点并返回一个SyncReference实例,唯一key以客户端生成的时间戳为前缀,以便生成的列表将按时间顺序排序。

SyncReference _counterRef = WilddogSync.instance.reference().child('counter');
SyncReference _messagesRef = WilddogSync.instance.reference().child('messages');

_counterRef.set('666');
_messagesRef.push().set(<String, String>{
  'content': 'message1Content',
  'userId': 'user1',
});

设置优先级

setPriority()方法用于设置节点的优先级,每个节点都能设置优先级,用于实现节点按优先级排序。优先级是节点的隐藏属性,默认为“0”。

_counterRef.setPriority(100);

更新数据

update方法用于更新指定子节点。

_messagesRef.child('messagesID').update({
  'content': 'message2Content',
  'userId': 'user2',
});

获取数据

使用once()方法可以获取当前节点的DataSnapshot实例,并通过DataSnapshot查看当前节点的key和value。由于获取数据是异步操作,因此需要导入相关的包并设置方法的返回值为Future类型。

// import 'dart:async';
Future<Null> _chestnuts() async {
  DataSnapshot snapshot = await _counterRef.once();
  print('${onValue.key} : ${onValue.value}');
}

或者使用Future的抽象方法then,注册一个在Future完成时调用的回调。

_counterRef.once().then((onValue){
  print('${onValue.key} : ${onValue.value}');
});

删除数据

remove方法用于删除指定节点。

_counterRef.remove();

监听数据

监听节点

onValue方法会返回一个监听当前节点值的Stream,再将其添加至StreamSubscription实例中。这样每当节点的值发生更改时,应用程序都会收到更改后的值。需要注意的是,在应用程序结束时,要关闭所有的StreamSubscription实例。

StreamSubscription<Event> _counterSubscription;

@override
void initState() {
  super.initState();
  _counterSubscription = _counterRef.onValue.listen((Event event) {
    print(event.snapshot.value);
  });
}

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

监听子节点

监听子节点事件的方法有四种,分别是以下的方法。

  • onChildAdded:子节点加入时触发事件。
  • onChildRemoved:子节点被移除时触发事件。
  • onChildChanged:子节点改变时触发事件。
  • onChildMoved:子节点被移动时触发事件。

onChildAdded方法为例,当前节点下添加了一个子节点时,应用程序会立即收到刚刚添加的子节点数据。要注意的是,在这四个方法中,onChildAdded方法会返回所有的子节点数据。

StreamSubscription<Event> _messagesSubscription;

@override
void initState() {
  super.initState();
  _messagesSubscription = _messagesRef.onChildAdded.listen((Event event){
    print('子节点增加了: ${event.snapshot.value}');
  });
}

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

子节点排序

将监听到的子节点排序有四种方法,分别是以下的方法。

  • orderByChild(String key):生成按特定子key的value排序的数据视图。
  • orderByKey():生成按Key排序的数据视图。
  • orderByValue():生成按Value排序的数据视图。
  • orderByPriority():生成按Priority排序的数据视图。

orderByChild(String key)方法为例,将所有子节点按特定子key的value排序,每当有新的子节点时,都会加入排序。

_messagesSubscription = _messagesRef.orderByChild("content").onChildAdded.listen((Event event){
  print('子节点增加了: ${event.snapshot.value}');
});

有限的监听

将监听到的子节点排序有两种方法,分别是以下的方法。

  • limitToFirst(int limit):从开头开始有限制的监听子节点。
  • limitToLast(int limit):从末尾(最新的子节点)开始有限制的监听子节点。

limitToFirst(int limit)方法为例,只监听从末尾开始的十个子节点。

_messagesSubscription = _messagesRef.limitToLast(10).onChildAdded.listen((Event event) {
  print('子节点增加了: ${event.snapshot.value}');
});

野狗动画列表

WilddogAnimatedList控件是一个绑定到Wilddog查询的滚动容器。在当前查询的节点下插入或移除子节点,会产生动画效果,使用户体验更好。在当前查询的节点下修改子节点,WilddogAnimatedList控件也会实时更新数据。

// import 'package:wilddog_sync/ui/wilddog_animated_list.dart';
// import 'dart:async';
new WilddogAnimatedList(
  query: _messagesRef,
  sort: (DataSnapshot a, DataSnapshot b) => b.key.compareTo(a.key),
  itemBuilder: (BuildContext context, DataSnapshot snapshot, Animation<double> animation, int index) {
    return new SizeTransition(
      sizeFactor: animation,
      child: new Text("$index: ${snapshot.value}"),
    );
  },
),
属性说明参数类型
key全局密钥GlobalKey
query用于填充列表的Wilddog查询SyncReference
itemBuilder根据需要调用的构建列表项控件WilddogAnimatedListItemBuilder
sort用于在排序列表时比较快照的方法(可选),默认值是按key对快照进行排序Comparator< DataSnapshot >
defaultChild在query加载时显示的控件,默认为空的Container()Widget
scrollDirection滚动视图中滚动轴的方向,默认为Axis.verticalAxis
reverse滚动视图是否在阅读方向滚动,默认为false,即从左到右滚动、从上到下滚动bool
controller用于控制滚动视图中滚动条位置的控制器对象ScrollController
primary这是否是与父PrimaryScrollController关联的主滚动视图bool
physics滚动视图应如何响应用户输入,默认为匹配平台约定ScrollPhysics
shrinkWrapscrollDirection中滚动视图的范围是否应由正在查看的内容确定,默认为falsebool
padding插入子控件的空间量EdgeInsets
duration插入和删除动画的持续时间,默认为300毫秒Duration

数据本地持久化

数据本地持久化是针对移动网络稳定性差而开发的功能。默认情况下,Wilddog Sync的数据存储在内存中,一旦重启,内存数据将被清除。开启数据本地持久化功能,可以使设备重启后无需再同步云端,有助于节省流量和提升重启后的访问速度。

setPersistenceEnabled(bool enabled)方法用于设置数据库持久性是否开启。必须在调用数据库引用方法之前设置此属性,并且每个应用程序只需要调用一次。

WilddogSync.instance.setPersistenceEnabled(true);

Wilddog Sync可以在查询数据前同步指定节点下的数据,并将数据存储到设备中,以此提升访问速度。通过在某个位置调用keepSynced(true),即使没有为该位置附加任何监听器,该位置的数据也将自动下载并保持同步。

_counterRef.keepSynced(true);

0.0.6

  • Updated README.md

0.0.5

  • Improved documentation
  • Improved example

0.0.4

  • Updated README.md
  • Added example app
  • Bug fixes to Query handling

0.0.3

  • Fix compilation error
  • Added removal and priority to SyncReference

0.0.2

  • Updated README.md
  • Improved documentation

0.0.1

  • Initial Release

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:wilddog_sync/wilddog_sync.dart';
import 'package:wilddog_sync/ui/wilddog_animated_list.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: '野狗实时通信引擎',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter;
  final SyncReference _counterRef =
  WilddogSync.instance.reference().child('counter');
  final SyncReference _messagesRef =
  WilddogSync.instance.reference().child('messages');
  StreamSubscription<Event> _counterSubscription;
  StreamSubscription<Event> _messagesSubscription;
  bool _anchorToBottom = false;

  String _kTestKey = 'Key值';
  String _kTestValue = 'Value值-';

  @override
  void initState() {
    super.initState();
    WilddogSync.instance.setPersistenceEnabled(true);
    _counterRef.keepSynced(true);
    _counterSubscription = _counterRef.onValue.listen((Event event) {
      setState(() {
        _counter = event.snapshot.value ?? 0;
      });
    });
    _messagesSubscription =
        _messagesRef.limitToLast(10).onChildAdded.listen((Event event) {
          print('子节点增加了: ${event.snapshot.value}');
        });
  }

  @override
  void dispose() {
    super.dispose();
    _messagesSubscription.cancel();
    _counterSubscription.cancel();
  }

  Future<Null> _increment() async {
    final DataSnapshot snapshot = await _counterRef.once();
    setState(() {
      _counter = (snapshot.value ?? 0) + 1;
    });
    _counterRef.set(_counter);
    _messagesRef
        .push()
        .set(<String, String>{_kTestKey: '$_kTestValue $_counter'});
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('野狗实时通信引擎'),
      ),
      body: new Column(
        children: <Widget>[
          new Flexible(
            child: new Center(
              child: new Text(
                '按钮点击了 $_counter 次,\n\n'
                    '数据来源于所有设备。',
              ),
            ),
          ),
          new ListTile(
            leading: new Checkbox(
              onChanged: (bool value) {
                setState(() {
                  _anchorToBottom = value;
                });
              },
              value: _anchorToBottom,
            ),
            title: const Text('锚点到底部'),
          ),
          new Flexible(
            child: new WilddogAnimatedList(
              key: new ValueKey<bool>(_anchorToBottom),
              query: _messagesRef,
              reverse: _anchorToBottom,
              sort: _anchorToBottom
                  ? (DataSnapshot a, DataSnapshot b) => b.key.compareTo(a.key)
                  : null,
              itemBuilder: (BuildContext context, DataSnapshot snapshot,
                  Animation<double> animation, int index) {
                return new SizeTransition(
                  sizeFactor: animation,
                  child: new Text("$index: ${snapshot.value.toString()}"),
                );
              },
            ),
          ),
        ],
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _increment,
        tooltip: '增加',
        child: new Icon(Icons.add),
      ),
    );
  }
}

1. Depend on it

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


dependencies:
  wilddog_sync: "^0.0.6"

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

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

3. Import it

Now in your Dart code, you can use:


import 'package:wilddog_sync/wilddog_sync.dart';
        
Version Uploaded Documentation Archive
0.0.6 Dec 6, 2017 Go to the documentation of wilddog_sync 0.0.6 Download wilddog_sync 0.0.6 archive
0.0.5 Nov 2, 2017 Go to the documentation of wilddog_sync 0.0.5 Download wilddog_sync 0.0.5 archive
0.0.4 Oct 25, 2017 Go to the documentation of wilddog_sync 0.0.4 Download wilddog_sync 0.0.4 archive
0.0.3 Oct 21, 2017 Go to the documentation of wilddog_sync 0.0.3 Download wilddog_sync 0.0.3 archive
0.0.2 Oct 18, 2017 Go to the documentation of wilddog_sync 0.0.2 Download wilddog_sync 0.0.2 archive
0.0.1 Oct 17, 2017 Go to the documentation of wilddog_sync 0.0.1 Download wilddog_sync 0.0.1 archive

Analysis

We analyzed this package on Apr 23, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.49.0
  • pana: 0.10.6
  • Flutter: 0.3.2

Scores

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

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

  • The description is too short.

    Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 10 hints.

    Run flutter format to format lib/src/event.dart.

    Run flutter format to format lib/src/query.dart.

    Similar analysis of the following files failed:

    • lib/src/sync_reference.dart (hint)
    • lib/src/utils/push_id_generator.dart (hint)
    • lib/src/wilddog_sync.dart (hint)
    • lib/ui/utils/stream_subscriber_mixin.dart (hint)
    • lib/ui/wilddog_animated_list.dart (hint)
    • lib/ui/wilddog_list.dart (hint)
    • lib/ui/wilddog_sorted_list.dart (hint)
    • lib/wilddog_sync.dart (hint)

Dependencies

Package Constraint Resolved Available
Direct dependencies
flutter 0.0.0
Transitive dependencies
collection 1.14.6 1.14.9
meta 1.1.2
sky_engine 0.0.99
typed_data 1.1.5
vector_math 2.0.6