From 9ad14d45d1713eff3431eaec335eac36b4e86e9a Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 9 Jan 2019 00:14:18 +0800 Subject: [PATCH 1/8] add some code document and update version to 0.0.3 --- lib/leancloud_flutter_plugin.dart | 64 +++++++++++++++++-------------- lib/leancloud_object.dart | 38 +++++++++++------- lib/leancloud_query.dart | 28 ++++++++++---- pubspec.yaml | 4 +- 4 files changed, 82 insertions(+), 52 deletions(-) diff --git a/lib/leancloud_flutter_plugin.dart b/lib/leancloud_flutter_plugin.dart index 5c89585..fad4a79 100644 --- a/lib/leancloud_flutter_plugin.dart +++ b/lib/leancloud_flutter_plugin.dart @@ -5,18 +5,24 @@ import 'package:flutter/services.dart'; import 'package:leancloud_flutter_plugin/leancloud_object.dart'; import 'package:leancloud_flutter_plugin/leancloud_query.dart'; +/// Leancloud flutter Plugin class LeancloudFlutterPlugin { + + /// method channel static const MethodChannel _channel = const MethodChannel('leancloud_flutter_plugin'); + /// Singleton property static LeancloudFlutterPlugin _instancePlugin = new LeancloudFlutterPlugin(); + /// Get plugin instance static LeancloudFlutterPlugin getInstance() { return _instancePlugin; } - int logLevel = 0; + int _logLevel = 0; + /// Initialize the Native SDK void initialize(String appId, String appKey) { Map args = { 'appId': appId, @@ -25,51 +31,45 @@ class LeancloudFlutterPlugin { _channel.invokeMethod('initialize', args); } - // - // Setup log level must be before call initialize function - // - // The call must be include args: - // level --> OFF(0), ERROR(1), WARNING(2), INFO(3), DEBUG(4), VERBOSE(5), ALL(6); - // + /// Setup log level must be before called initialize function + /// The call must be include args: + /// [level] --> OFF(0), ERROR(1), WARNING(2), INFO(3), DEBUG(4), VERBOSE(5), ALL(6); void setLogLevel(LeancloudLoggerLevel level) { switch (level) { case LeancloudLoggerLevel.OFF: - this.logLevel = 0; + this._logLevel = 0; break; case LeancloudLoggerLevel.ERROR: - this.logLevel = 1; + this._logLevel = 1; break; case LeancloudLoggerLevel.WARNING: - this.logLevel = 2; + this._logLevel = 2; break; case LeancloudLoggerLevel.INFO: - this.logLevel = 3; + this._logLevel = 3; break; case LeancloudLoggerLevel.DEBUG: - this.logLevel = 4; + this._logLevel = 4; break; case LeancloudLoggerLevel.VERBOSE: - this.logLevel = 5; + this._logLevel = 5; break; case LeancloudLoggerLevel.ALL: - this.logLevel = 6; + this._logLevel = 6; break; } Map args = { - 'level': this.logLevel, + 'level': this._logLevel, }; _channel.invokeMethod('setLogLevel', args); } - // - // Setup region must be before call initialize function - // - // The call must be include args: - // region --> NorthChina(0), EastChina(1), NorthAmerica(2) - // REGION.NorthChina - this is default value - // REGION.EastChina - // REGION.NorthAmerica - // + /// Setup region must be before called initialize function + /// The call must be include args: + /// [region] --> NorthChina(0), EastChina(1), NorthAmerica(2) + /// REGION.NorthChina - this is default value + /// REGION.EastChina + /// REGION.NorthAmerica void setRegion(LeancloudCloudRegion region) { int regionValue; switch (region) { @@ -89,30 +89,36 @@ class LeancloudFlutterPlugin { _channel.invokeMethod('setRegion', args); } - // save object + /// Save AVObject. + /// Usually suggest using AVObject.save() function instead of this. Future saveOrCreate(AVObject object) async { Map args = {'avObject': object.toString()}; String objectString = await _channel.invokeMethod('saveOrCreate', args); - if (this.logLevel != 0) { + if (this._logLevel != 0) { print("[saveOrCreate function] -> " + objectString); } return objectString; } - // delete object + /// Delete object + /// Usually suggest using AVObject.delete() function instead of this. Future delete(AVObject object) async { Map args = {'avObject': object.toString()}; return await _channel.invokeMethod('delete', args); } - // query object + /// Query object + /// Usually suggest using AVQuery instead of this. Future query(AVQuery query) async { Map args = {'avQuery': query.toString()}; return await _channel.invokeMethod('query', args); } } - +/// Leancloud logger level +/// iOS only have ON or OFF. So when you set OFF, it's OFF. When you set another logger level, it's ON. enum LeancloudLoggerLevel { OFF, ERROR, WARNING, INFO, DEBUG, VERBOSE, ALL } +/// Leancloud Region +/// iOS not have this property enum LeancloudCloudRegion { NorthChina, EastChina, NorthAmerica } diff --git a/lib/leancloud_object.dart b/lib/leancloud_object.dart index 6804ade..fb0dab6 100644 --- a/lib/leancloud_object.dart +++ b/lib/leancloud_object.dart @@ -4,47 +4,56 @@ import 'package:leancloud_flutter_plugin/leancloud_flutter_plugin.dart'; class AVObject { - String className; - Map fields; + /// private property for Class Name + String _className; + /// private property for Class Fields + Map _fields; - AVObject(this.className); + /// Create an AVObject with Class Name + AVObject(this._className); - // this function will change className! + /// Never call this function manually. + /// This function used for AVQuery. It's convert from string to AVObject. AVObject fromQuery(String queriedString) { Map queriedFields = jsonDecode(queriedString); queriedFields.forEach((key, value) { - if (key == "className") className = value; + if (key == "className") this._className = value; this.put(key, value); }); return this; } + /// Add or Update field value with [value] into this Object by [key] void put(String key, Object value) { - if (fields == null) { - fields = new Map(); + if (this._fields == null) { + this._fields = new Map(); } - fields.addAll({key: value}); + this._fields.addAll({key: value}); } + /// Get this Object Id String getObjectId() { - return fields["objectId"]; + return this._fields["objectId"]; } + /// Get [key] field value dynamic get(String key) { - return fields[key]; + return this._fields[key]; } + /// Overwritten toString() function, to return this object's JSON string. String toString() { - if (fields == null) { + if (this._fields == null) { throw Exception("Empty field, before save or create, you must to add field!"); } - String fieldsString = jsonEncode(fields); + String fieldsString = jsonEncode(this._fields); Map object = new Map(); - object.addAll({"className": className}); + object.addAll({"className": this._className}); object.addAll({"fields": fieldsString}); return jsonEncode(object); } + /// Save or Update this object to leancloud database Future save() async { LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); String objectString = await leancloudFlutterPlugin.saveOrCreate(this); @@ -52,12 +61,15 @@ class AVObject { return this; } + /// Delete this object from leancloud database + /// But this object value will still in memory, until you manually set this object to null. Future delete() async { LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); bool isDeleted = await leancloudFlutterPlugin.delete(this); return isDeleted; } + /// add system fields into this object. void _addSystemFields(String objectString) { Map systemFields = jsonDecode(objectString); systemFields.forEach((key, value) { diff --git a/lib/leancloud_query.dart b/lib/leancloud_query.dart index e85fd0a..b046505 100644 --- a/lib/leancloud_query.dart +++ b/lib/leancloud_query.dart @@ -5,21 +5,26 @@ import 'package:leancloud_flutter_plugin/leancloud_object.dart'; class AVQuery { - String className; - List> queries; + /// private property for Class Name + String _className; + /// private property for query conditions + List> _queries; - AVQuery(this.className) { - queries = new List(); + /// Create an AVQuery with Class Name + AVQuery(this._className) { + this._queries = new List(); } + /// Overwritten toString() function, to return this object's JSON string. String toString() { - String queriesString = jsonEncode(queries); + String queriesString = jsonEncode(this._queries); Map object = new Map(); - object.addAll({"className": className}); + object.addAll({"className": _className}); object.addAll({"queries": queriesString}); return jsonEncode(object); } + /// Get an AVObject object by object Id Future get(String objectId) async { _setQueriesValue("get", objectId, null); LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); @@ -29,12 +34,12 @@ class AVQuery { return object; } + /// Find AVObjects with all conditions Future> find() async { LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); String objectsString = await leancloudFlutterPlugin.query(this); Map objectsJson = jsonDecode(objectsString); List lists = new List(); - //TODO for (String objectString in objectsJson["objects"]) { AVObject object = new AVObject(""); object.fromQuery(objectString); @@ -43,36 +48,43 @@ class AVQuery { return lists; } + /// Set equal to condition AVQuery whereEqualTo(String key, dynamic value) { _setQueriesValue("equalTo", key, value); return this; } + /// Set not equal to condition AVQuery whereNotEqualTo(String key, dynamic value) { _setQueriesValue("notEqualTo", key, value); return this; } + /// Set greater than condition AVQuery whereGreaterThan(String key, dynamic value) { _setQueriesValue("greaterThan", key, value); return this; } + /// Set greater than or equal to condition AVQuery whereGreaterThanOrEqualTo(String key, dynamic value) { _setQueriesValue("greaterThanOrEqualTo", key, value); return this; } + /// Set less than condition AVQuery whereLessThan(String key, dynamic value) { _setQueriesValue("lessThan", key, value); return this; } + /// Set where less than or equal to condition AVQuery whereLessThanOrEqualTo(String key, dynamic value) { _setQueriesValue("lessThanOrEqualTo", key, value); return this; } + /// Private function, set conditions json value _setQueriesValue(String queryMethod, dynamic arg1, dynamic arg2) { Map queryClass = new Map(); queryClass.addAll({"queryMethod": queryMethod}); @@ -80,6 +92,6 @@ class AVQuery { if (arg2 != null) { queryClass.addAll({"arg2": arg2}); } - queries.add(queryClass); + this._queries.add(queryClass); } } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 5a23e75..33c1606 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: leancloud_flutter_plugin -description: LeanCloud flutter plugin by Luna Gao -version: 0.0.2 +description: LeanCloud flutter plugin by Luna Gao. This is a third-party leancloud plugin package. Committed to becoming a plugin consistent with the official SDK usage. +version: 0.0.3 author: Luna Gao homepage: https://github.com/LunaGao/leancloud_flutter_plugin From b23966ef2367e0fbc59558b20cb363637f24e504 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 9 Jan 2019 00:24:30 +0800 Subject: [PATCH 2/8] update readme file --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 94688c8..1ceae29 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [Dark packages](https://pub.dartlang.org/packages/leancloud_flutter_plugin) -Developing by IntelliJ IDEA. +## Description +This plugin depends on Leancloud Native(iOS / Android) SDK. It's just convert the code from dart to those native language(Objective-C / Java). ## Getting Started From f6e00b41a1da686c161fdd258fbafc976b77d565 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 9 Jan 2019 00:44:56 +0800 Subject: [PATCH 3/8] do some `Effective Dart: Usage` --- lib/leancloud_flutter_plugin.dart | 16 ++++++++-------- lib/leancloud_object.dart | 27 ++++++++++++--------------- lib/leancloud_query.dart | 30 ++++++++++++++---------------- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/lib/leancloud_flutter_plugin.dart b/lib/leancloud_flutter_plugin.dart index fad4a79..b0599e1 100644 --- a/lib/leancloud_flutter_plugin.dart +++ b/lib/leancloud_flutter_plugin.dart @@ -20,11 +20,11 @@ class LeancloudFlutterPlugin { return _instancePlugin; } - int _logLevel = 0; + var _logLevel = 0; /// Initialize the Native SDK void initialize(String appId, String appKey) { - Map args = { + var args = { 'appId': appId, 'appKey': appKey, }; @@ -58,7 +58,7 @@ class LeancloudFlutterPlugin { this._logLevel = 6; break; } - Map args = { + var args = { 'level': this._logLevel, }; _channel.invokeMethod('setLogLevel', args); @@ -83,7 +83,7 @@ class LeancloudFlutterPlugin { regionValue = 2; break; } - Map args = { + var args = { 'region': regionValue, }; _channel.invokeMethod('setRegion', args); @@ -92,8 +92,8 @@ class LeancloudFlutterPlugin { /// Save AVObject. /// Usually suggest using AVObject.save() function instead of this. Future saveOrCreate(AVObject object) async { - Map args = {'avObject': object.toString()}; - String objectString = await _channel.invokeMethod('saveOrCreate', args); + var args = {'avObject': object.toString()}; + var objectString = await _channel.invokeMethod('saveOrCreate', args); if (this._logLevel != 0) { print("[saveOrCreate function] -> " + objectString); } @@ -103,14 +103,14 @@ class LeancloudFlutterPlugin { /// Delete object /// Usually suggest using AVObject.delete() function instead of this. Future delete(AVObject object) async { - Map args = {'avObject': object.toString()}; + var args = {'avObject': object.toString()}; return await _channel.invokeMethod('delete', args); } /// Query object /// Usually suggest using AVQuery instead of this. Future query(AVQuery query) async { - Map args = {'avQuery': query.toString()}; + var args = {'avQuery': query.toString()}; return await _channel.invokeMethod('query', args); } } diff --git a/lib/leancloud_object.dart b/lib/leancloud_object.dart index fb0dab6..0ec3572 100644 --- a/lib/leancloud_object.dart +++ b/lib/leancloud_object.dart @@ -5,9 +5,9 @@ import 'package:leancloud_flutter_plugin/leancloud_flutter_plugin.dart'; class AVObject { /// private property for Class Name - String _className; + var _className; /// private property for Class Fields - Map _fields; + var _fields = {}; /// Create an AVObject with Class Name AVObject(this._className); @@ -15,7 +15,7 @@ class AVObject { /// Never call this function manually. /// This function used for AVQuery. It's convert from string to AVObject. AVObject fromQuery(String queriedString) { - Map queriedFields = jsonDecode(queriedString); + var queriedFields = jsonDecode(queriedString); queriedFields.forEach((key, value) { if (key == "className") this._className = value; this.put(key, value); @@ -25,9 +25,6 @@ class AVObject { /// Add or Update field value with [value] into this Object by [key] void put(String key, Object value) { - if (this._fields == null) { - this._fields = new Map(); - } this._fields.addAll({key: value}); } @@ -43,11 +40,11 @@ class AVObject { /// Overwritten toString() function, to return this object's JSON string. String toString() { - if (this._fields == null) { - throw Exception("Empty field, before save or create, you must to add field!"); + if (this._fields.isEmpty) { + throw Exception("Empty field, before save or create, you must to add field! Using put() function."); } - String fieldsString = jsonEncode(this._fields); - Map object = new Map(); + var fieldsString = jsonEncode(this._fields); + var object = {}; object.addAll({"className": this._className}); object.addAll({"fields": fieldsString}); return jsonEncode(object); @@ -55,8 +52,8 @@ class AVObject { /// Save or Update this object to leancloud database Future save() async { - LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); - String objectString = await leancloudFlutterPlugin.saveOrCreate(this); + var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); + var objectString = await leancloudFlutterPlugin.saveOrCreate(this); _addSystemFields(objectString); return this; } @@ -64,14 +61,14 @@ class AVObject { /// Delete this object from leancloud database /// But this object value will still in memory, until you manually set this object to null. Future delete() async { - LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); - bool isDeleted = await leancloudFlutterPlugin.delete(this); + var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); + var isDeleted = await leancloudFlutterPlugin.delete(this); return isDeleted; } /// add system fields into this object. void _addSystemFields(String objectString) { - Map systemFields = jsonDecode(objectString); + var systemFields = jsonDecode(objectString); systemFields.forEach((key, value) { this.put(key, value); }); diff --git a/lib/leancloud_query.dart b/lib/leancloud_query.dart index b046505..bc4b3eb 100644 --- a/lib/leancloud_query.dart +++ b/lib/leancloud_query.dart @@ -6,19 +6,17 @@ import 'package:leancloud_flutter_plugin/leancloud_object.dart'; class AVQuery { /// private property for Class Name - String _className; + var _className; /// private property for query conditions - List> _queries; + var _queries = []; /// Create an AVQuery with Class Name - AVQuery(this._className) { - this._queries = new List(); - } + AVQuery(this._className); /// Overwritten toString() function, to return this object's JSON string. String toString() { - String queriesString = jsonEncode(this._queries); - Map object = new Map(); + var queriesString = jsonEncode(this._queries); + var object = {}; object.addAll({"className": _className}); object.addAll({"queries": queriesString}); return jsonEncode(object); @@ -27,20 +25,20 @@ class AVQuery { /// Get an AVObject object by object Id Future get(String objectId) async { _setQueriesValue("get", objectId, null); - LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); - String objectString = await leancloudFlutterPlugin.query(this); - AVObject object = new AVObject(""); + var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); + var objectString = await leancloudFlutterPlugin.query(this); + var object = new AVObject(""); object.fromQuery(objectString); return object; } /// Find AVObjects with all conditions Future> find() async { - LeancloudFlutterPlugin leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); - String objectsString = await leancloudFlutterPlugin.query(this); - Map objectsJson = jsonDecode(objectsString); - List lists = new List(); - for (String objectString in objectsJson["objects"]) { + var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); + var objectsString = await leancloudFlutterPlugin.query(this); + var objectsJson = jsonDecode(objectsString); + List lists = []; + for (var objectString in objectsJson["objects"]) { AVObject object = new AVObject(""); object.fromQuery(objectString); lists.add(object); @@ -86,7 +84,7 @@ class AVQuery { /// Private function, set conditions json value _setQueriesValue(String queryMethod, dynamic arg1, dynamic arg2) { - Map queryClass = new Map(); + var queryClass = {}; queryClass.addAll({"queryMethod": queryMethod}); queryClass.addAll({"arg1": arg1}); if (arg2 != null) { From 4c07336ad06cb3ab9f62e94de68508c4abb4e75a Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 10 Jan 2019 00:19:00 +0800 Subject: [PATCH 4/8] add android query --- .../LeancloudQuery.java | 99 +++++++++++++++---- 1 file changed, 78 insertions(+), 21 deletions(-) diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java index cfff4b6..71d5adf 100644 --- a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java @@ -1,6 +1,7 @@ package com.lunagao.leancloudflutterplugin; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import java.lang.reflect.InvocationTargetException; @@ -10,6 +11,8 @@ import cn.leancloud.AVQuery; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; class LeancloudQuery { @@ -34,33 +37,87 @@ class LeancloudQuery { * @param call MethodCall from LeancloudFlutterPlugin.onMethodCall function * @param result MethodChannel.Result from LeancloudFlutterPlugin.onMethodCall function */ - void query(MethodCall call, MethodChannel.Result result) { + void query(MethodCall call, final MethodChannel.Result result) { JSONObject avQueryJson = LeancloudArgsConverter.getAVQueryJsonObject(call, result); assert avQueryJson != null; String className = avQueryJson.getString("className"); - String fieldsString = avQueryJson.getString("queries"); - JSONObject fieldsJson = JSON.parseObject(fieldsString); + String queriesString = avQueryJson.getString("queries"); + JSONArray queriesJson = JSON.parseArray(queriesString); AVQuery avQuery = new AVQuery<>(className); - try { - if (fieldsJson.size() == 1 && fieldsJson.containsKey("get")) { -// AVObject object = avQuery.get(fieldsJson.getString("get")); - List objects = avQuery.find(); - AVObject object = avQuery.get("5c31b14544d904005d1e773c"); - result.success(object); -// result.success("Android " + android.os.Build.VERSION.RELEASE); + for (Object oneQueryObject : queriesJson) { + JSONObject oneQuery; + if (oneQueryObject instanceof JSONObject) { + oneQuery = (JSONObject) oneQueryObject; + } else { + oneQuery = (JSONObject) JSON.toJSON(oneQueryObject); + } + + switch (oneQuery.getString("queryMethod")) { + case "get": + avQuery.getInBackground(oneQuery.getString("arg1")).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable disposable) {} + + @Override + public void onNext(AVObject avObject) { + result.success(avObject.toJSONObject().toJSONString()); + } + + @Override + public void onError(Throwable throwable) { + result.error("leancloud-error", throwable.getMessage(), null); + } + + @Override + public void onComplete() {} + }); + return; + case "equalTo": + avQuery.whereEqualTo(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + case "notEqualTo": + avQuery.whereNotEqualTo(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + case "greaterThan": + avQuery.whereGreaterThan(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + case "greaterThanOrEqualTo": + avQuery.whereGreaterThanOrEqualTo(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + case "lessThan": + avQuery.whereLessThan(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + case "lessThanOrEqualTo": + avQuery.whereLessThanOrEqualTo(oneQuery.getString("arg1"), oneQuery.get("arg2")); + break; + default: + result.error("params-error", "no such query queryMethod name, please check again", null); + break; } - //TODO list need to be JSON type -// result.success(list); - } catch (Exception ex) { - result.error("aaa" + ex.getMessage(), null, null); } -// } catch (NoSuchMethodException ex) { -// result.error("NoSuchMethodException, please check queryMethod", null, null); -// } catch (IllegalAccessException ex) { -// result.error("IllegalAccessException, Do you call an illegal access method?", null, null); -// } catch (InvocationTargetException ex) { -// result.error("InvocationTargetException, I don't know what's happen,:( check everything again?", null, null); -// } + avQuery.findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable disposable) {} + + @Override + public void onNext(List avObjects) { + JSONObject jsonObject = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + for (AVObject object : avObjects) { + jsonArray.add(object.toJSONObject().toJSONString()); + } + jsonObject.put("objects", jsonArray); + result.success(jsonObject.toJSONString()); + } + + @Override + public void onError(Throwable throwable) { + result.error("leancloud-error", throwable.getMessage(), null); + } + + @Override + public void onComplete() {} + }); } } From e10f8a14d482e20e989e65dcddcb0aea92204e53 Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 10 Jan 2019 00:56:28 +0800 Subject: [PATCH 5/8] add CQL android, but it can't query any thing --- .../LeancloudFlutterPlugin.java | 4 +++ .../LeancloudQuery.java | 29 +++++++++++++++++++ example/lib/list_screen.dart | 12 ++++++++ lib/leancloud_flutter_plugin.dart | 9 +++++- lib/leancloud_query.dart | 14 +++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudFlutterPlugin.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudFlutterPlugin.java index 6afd20b..3776a2e 100644 --- a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudFlutterPlugin.java +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudFlutterPlugin.java @@ -44,6 +44,10 @@ public void onMethodCall(MethodCall call, Result result) { LeancloudQuery leancloudQuery = new LeancloudQuery(); leancloudQuery.query(call, result); break; + case "doCloudQuery": + LeancloudQuery doCloudQueryQuery = new LeancloudQuery(); + doCloudQueryQuery.doCloudQuery(call, result); + break; default: result.notImplemented(); } diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java index 71d5adf..c676878 100644 --- a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java @@ -9,6 +9,7 @@ import cn.leancloud.AVObject; import cn.leancloud.AVQuery; +import cn.leancloud.query.AVCloudQueryResult; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.reactivex.Observer; @@ -120,4 +121,32 @@ public void onError(Throwable throwable) { public void onComplete() {} }); } + + void doCloudQuery(MethodCall call, final MethodChannel.Result result) { + String cqlString = LeancloudArgsConverter.getStringValue(call, result, "cql"); + AVQuery.doCloudQueryInBackground(cqlString).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable disposable) {} + + @Override + public void onNext(AVCloudQueryResult avCloudQueryResult) { + List avObjects = avCloudQueryResult.getResults(); + JSONObject jsonObject = new JSONObject(); + JSONArray jsonArray = new JSONArray(); + for (AVObject object : avObjects) { + jsonArray.add(object.toJSONObject().toJSONString()); + } + jsonObject.put("objects", jsonArray); + result.success(jsonObject.toJSONString()); + } + + @Override + public void onError(Throwable throwable) { + result.error("leancloud-error", throwable.getMessage(), null); + } + + @Override + public void onComplete() {} + }); + } } diff --git a/example/lib/list_screen.dart b/example/lib/list_screen.dart index fe0f927..ff51a03 100644 --- a/example/lib/list_screen.dart +++ b/example/lib/list_screen.dart @@ -69,6 +69,14 @@ class _ListScreenState extends State { }); } + _queryByCQL() { + var cql = "select * from DemoObject where int_value = 20"; + AVQuery.doCloudQuery(cql).then((objects) { + print(objects); + print("Queryed!"); + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -107,6 +115,10 @@ class _ListScreenState extends State { onPressed: _queryAllObject, child: Text('query all Objects'), ), + FlatButton( + onPressed: _queryByCQL, + child: Text('query by CQL'), + ), ], ) ); diff --git a/lib/leancloud_flutter_plugin.dart b/lib/leancloud_flutter_plugin.dart index b0599e1..4426532 100644 --- a/lib/leancloud_flutter_plugin.dart +++ b/lib/leancloud_flutter_plugin.dart @@ -107,12 +107,19 @@ class LeancloudFlutterPlugin { return await _channel.invokeMethod('delete', args); } - /// Query object + /// Query object(s) /// Usually suggest using AVQuery instead of this. Future query(AVQuery query) async { var args = {'avQuery': query.toString()}; return await _channel.invokeMethod('query', args); } + + /// Using CQL Query object(s) + /// Usually suggest using AVQuery instead of this. + Future doCloudQuery(String cql) async { + var args = {'cql': cql}; + return await _channel.invokeMethod('doCloudQuery', args); + } } /// Leancloud logger level diff --git a/lib/leancloud_query.dart b/lib/leancloud_query.dart index bc4b3eb..a6de59b 100644 --- a/lib/leancloud_query.dart +++ b/lib/leancloud_query.dart @@ -10,6 +10,20 @@ class AVQuery { /// private property for query conditions var _queries = []; + /// CQL query + static Future> doCloudQuery(String cql) async { + var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); + var objectsString = await leancloudFlutterPlugin.doCloudQuery(cql); + var objectsJson = jsonDecode(objectsString); + List lists = []; + for (var objectString in objectsJson["objects"]) { + AVObject object = new AVObject(""); + object.fromQuery(objectString); + lists.add(object); + } + return lists; + } + /// Create an AVQuery with Class Name AVQuery(this._className); From 2f3c6e0794ee570f8522f584050a3144bbeec229 Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 10 Jan 2019 23:26:32 +0800 Subject: [PATCH 6/8] add ascending / descending / limit / skip function --- .../LeancloudObject.java | 2 + .../LeancloudQuery.java | 19 +++++++- example/lib/list_screen.dart | 2 + ios/Classes/LeancloudQuery.m | 44 ++++++++++++++----- lib/leancloud_query.dart | 36 +++++++++++++++ 5 files changed, 90 insertions(+), 13 deletions(-) diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudObject.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudObject.java index 02f3921..da0c4a0 100644 --- a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudObject.java +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudObject.java @@ -3,6 +3,8 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import java.util.List; + import cn.leancloud.AVObject; import cn.leancloud.types.AVNull; import io.flutter.plugin.common.MethodCall; diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java index c676878..d81f5b5 100644 --- a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudQuery.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import java.lang.reflect.InvocationTargetException; import java.util.List; import cn.leancloud.AVObject; @@ -91,6 +90,24 @@ public void onComplete() {} case "lessThanOrEqualTo": avQuery.whereLessThanOrEqualTo(oneQuery.getString("arg1"), oneQuery.get("arg2")); break; + case "orderByAscending": + avQuery.orderByAscending(oneQuery.getString("arg1")); + break; + case "orderByDescending": + avQuery.orderByDescending(oneQuery.getString("arg1")); + break; + case "addAscendingOrder": + avQuery.addAscendingOrder(oneQuery.getString("arg1")); + break; + case "addDescendingOrder": + avQuery.addDescendingOrder(oneQuery.getString("arg1")); + break; + case "limit": + avQuery.limit(oneQuery.getIntValue("arg1")); + break; + case "skip": + avQuery.skip(oneQuery.getIntValue("arg1")); + break; default: result.error("params-error", "no such query queryMethod name, please check again", null); break; diff --git a/example/lib/list_screen.dart b/example/lib/list_screen.dart index ff51a03..f0c5392 100644 --- a/example/lib/list_screen.dart +++ b/example/lib/list_screen.dart @@ -63,6 +63,8 @@ class _ListScreenState extends State { // avQuery.whereGreaterThanOrEqualTo("int_value", 20); // avQuery.whereLessThan("int_value", 20); // avQuery.whereLessThanOrEqualTo("int_value", 20); + avQuery.limit(10); + avQuery.skip(1); avQuery.find().then((objects) { print("All Objects Queryed!"); setState(() { }); diff --git a/ios/Classes/LeancloudQuery.m b/ios/Classes/LeancloudQuery.m index 8b19b84..ad44b3c 100644 --- a/ios/Classes/LeancloudQuery.m +++ b/ios/Classes/LeancloudQuery.m @@ -11,6 +11,10 @@ @implementation LeancloudQuery +const NSString *QUERYMETHOD = @"queryMethod"; +const NSString *ARG1 = @"arg1"; +const NSString *ARG2 = @"arg2"; + - (void) query:(FlutterMethodCall*)call result:(FlutterResult)result { NSDictionary *avQueryJson = [LeancloudArgsConverter getAVQueryJsonObject:call result:result]; NSString *className = avQueryJson[@"className"]; @@ -28,18 +32,34 @@ - (void) query:(FlutterMethodCall*)call result:(FlutterResult)result { return; }]; } - if([oneQuery[@"queryMethod"] isEqualToString:@"equalTo"]) { - [query whereKey:oneQuery[@"arg1"] equalTo:oneQuery[@"arg2"]]; - } else if([oneQuery[@"queryMethod"] isEqualToString:@"notEqualTo"]) { - [query whereKey:oneQuery[@"arg1"] notEqualTo:oneQuery[@"arg2"]]; - } else if([oneQuery[@"queryMethod"] isEqualToString:@"greaterThan"]) { - [query whereKey:oneQuery[@"arg1"] greaterThan:oneQuery[@"arg2"]]; - } else if([oneQuery[@"queryMethod"] isEqualToString:@"greaterThanOrEqualTo"]) { - [query whereKey:oneQuery[@"arg1"] greaterThanOrEqualTo:oneQuery[@"arg2"]]; - } else if([oneQuery[@"queryMethod"] isEqualToString:@"lessThan"]) { - [query whereKey:oneQuery[@"arg1"] lessThan:oneQuery[@"arg2"]]; - } else if([oneQuery[@"queryMethod"] isEqualToString:@"lessThanOrEqualTo"]) { - [query whereKey:oneQuery[@"arg1"] lessThanOrEqualTo:oneQuery[@"arg2"]]; + if([oneQuery[QUERYMETHOD] isEqualToString:@"equalTo"]) { + [query whereKey:oneQuery[ARG1] equalTo:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"notEqualTo"]) { + [query whereKey:oneQuery[ARG1] notEqualTo:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"greaterThan"]) { + [query whereKey:oneQuery[ARG1] greaterThan:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"greaterThanOrEqualTo"]) { + [query whereKey:oneQuery[ARG1] greaterThanOrEqualTo:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"lessThan"]) { + [query whereKey:oneQuery[ARG1] lessThan:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"lessThanOrEqualTo"]) { + [query whereKey:oneQuery[ARG1] lessThanOrEqualTo:oneQuery[ARG2]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"orderByAscending"]) { + [query orderByAscending:oneQuery[ARG1]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"orderByDescending"]) { + [query orderByDescending:oneQuery[ARG1]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"addAscendingOrder"]) { + [query addDescendingOrder:oneQuery[ARG1]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"addDescendingOrder"]) { + [query addDescendingOrder:oneQuery[ARG1]]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"limit"]) { + query.limit = [oneQuery[ARG1] intValue]; + } else if([oneQuery[QUERYMETHOD] isEqualToString:@"skip"]) { + query.skip = [oneQuery[ARG1] intValue]; + } else { + result([FlutterError errorWithCode:@"params-error" + message:@"no such query queryMethod name, please check again" + details:[NSString stringWithFormat:@"no such query queryMethod name, %@", oneQuery[QUERYMETHOD]]]); } } [query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) { diff --git a/lib/leancloud_query.dart b/lib/leancloud_query.dart index a6de59b..27872d6 100644 --- a/lib/leancloud_query.dart +++ b/lib/leancloud_query.dart @@ -60,6 +60,42 @@ class AVQuery { return lists; } + /// set query result limit count + AVQuery limit(int limit) { + _setQueriesValue("limit", limit, null); + return this; + } + + /// set query result by ascending + AVQuery orderByAscending(String key) { + _setQueriesValue("orderByAscending", key, null); + return this; + } + + /// set query result by descending + AVQuery orderByDescending(String key) { + _setQueriesValue("orderByDescending", key, null); + return this; + } + + /// set query order by [key] column ascending + AVQuery addAscendingOrder(String key) { + _setQueriesValue("addAscendingOrder", key, null); + return this; + } + + /// set query order by [key] column descending + AVQuery addDescendingOrder(String key) { + _setQueriesValue("addDescendingOrder", key, null); + return this; + } + + /// set query result skip count + AVQuery skip(int skip) { + _setQueriesValue("skip", skip, null); + return this; + } + /// Set equal to condition AVQuery whereEqualTo(String key, dynamic value) { _setQueriesValue("equalTo", key, value); From 045f4ce5a372db393c3fa7555843f69ff340b5ed Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 10 Jan 2019 23:46:16 +0800 Subject: [PATCH 7/8] add user screen example --- .../leancloudflutterplugin/LeancloudUser.java | 14 ++++++++ example/lib/list_screen.dart | 12 +++++++ example/lib/user_screen.dart | 33 +++++++++++++++++++ lib/leancloud_flutter_plugin.dart | 6 ++++ lib/leancloud_user.dart | 15 +++++++++ 5 files changed, 80 insertions(+) create mode 100644 android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudUser.java create mode 100644 example/lib/user_screen.dart create mode 100644 lib/leancloud_user.dart diff --git a/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudUser.java b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudUser.java new file mode 100644 index 0000000..7e06d83 --- /dev/null +++ b/android/src/main/java/com/lunagao/leancloudflutterplugin/LeancloudUser.java @@ -0,0 +1,14 @@ +package com.lunagao.leancloudflutterplugin; + +import cn.leancloud.AVUser; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +public class LeancloudUser { + + void getCurrentUser(MethodCall call, final MethodChannel.Result result) { + AVUser currentUser = AVUser.getCurrentUser(); + result.success(currentUser.toJSONString()); + } + +} diff --git a/example/lib/list_screen.dart b/example/lib/list_screen.dart index f0c5392..f5fdae4 100644 --- a/example/lib/list_screen.dart +++ b/example/lib/list_screen.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:leancloud_flutter_plugin/leancloud_object.dart'; import 'package:leancloud_flutter_plugin/leancloud_query.dart'; +import 'user_screen.dart'; + class ListScreen extends StatefulWidget { @override _ListScreenState createState() => _ListScreenState(); @@ -121,6 +123,16 @@ class _ListScreenState extends State { onPressed: _queryByCQL, child: Text('query by CQL'), ), + Text('login function'), + FlatButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => UserScreen()), + ); + }, + child: Text('LOGIN'), + ), ], ) ); diff --git a/example/lib/user_screen.dart b/example/lib/user_screen.dart new file mode 100644 index 0000000..40a6c09 --- /dev/null +++ b/example/lib/user_screen.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class UserScreen extends StatefulWidget { + @override + _UserScreenState createState() => _UserScreenState(); +} + +class _UserScreenState extends State { + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('User Page'), + ), + body: ListView( + shrinkWrap: true, + padding: const EdgeInsets.all(20.0), + children: [ + Text("Please click 'create an Object' button"), + FlatButton( + onPressed: () {}, + child: Text('Sign in'), + ), + FlatButton( + onPressed: () {}, + child: Text('Login in'), + ) + ], + ) + ); + } +} \ No newline at end of file diff --git a/lib/leancloud_flutter_plugin.dart b/lib/leancloud_flutter_plugin.dart index 4426532..7da6c22 100644 --- a/lib/leancloud_flutter_plugin.dart +++ b/lib/leancloud_flutter_plugin.dart @@ -120,6 +120,12 @@ class LeancloudFlutterPlugin { var args = {'cql': cql}; return await _channel.invokeMethod('doCloudQuery', args); } + + /// Get current User + Future currentUser() async { + var currentUserJson = await _channel.invokeMethod('currentUser'); + return currentUserJson; + } } /// Leancloud logger level diff --git a/lib/leancloud_user.dart b/lib/leancloud_user.dart new file mode 100644 index 0000000..d8d9b0e --- /dev/null +++ b/lib/leancloud_user.dart @@ -0,0 +1,15 @@ +import 'package:leancloud_flutter_plugin/leancloud_flutter_plugin.dart'; +import 'package:leancloud_flutter_plugin/leancloud_object.dart'; + +class AVUser extends AVObject{ + + var _userName; + + AVUser() : super("_User"); + +// AVUser currentUser() { +// var leancloudFlutterPlugin = LeancloudFlutterPlugin.getInstance(); +// String jsonString = leancloudFlutterPlugin.currentUser(); +// return leancloudFlutterPlugin.currentUser(); +// } +} \ No newline at end of file From 5f0e2a00765fe53eb490f2fb6d6b0e18369be80a Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 10 Jan 2019 23:49:17 +0800 Subject: [PATCH 8/8] change change log --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c34e10..89ffc4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.0.3 + +* add query function + * orderByAscending + * orderByDescending + * addAscendingOrder + * addDescendingOrder + * limit + * skip +* Fixed query object by objectId on Android + ## 0.0.2 * fixed android package error.