Code Monkey home page Code Monkey logo

schema_widget's Introduction

GitHub issues GitHub forks GitHub stars GitHub license Pub Likes Pub Points Popularity style: effective dart GitHub tag (latest SemVer) GitHub top language GitHub contributors GitHub last commit Flutter CI

Convert JSON to Widget validating with JSON Schema for Flutter apps

What is it

The schema_widget is a Flutter package implemented with base on dynamic_widget package that produces widgets dynamically interpreting JSON objects.

Author

Writed by Alex Manoel Ferreira Silva Support - Recommend/Endorse me on LinkedIn

Under Legytma Soluções Inteligentes Company - Legytma Soluções Inteligentes in LinkedIn

Motivation

A major difficulty for any application developer is to ensure that all users keep their applications up to date to ensure the same user experience and to reduce the time required to fix bugs.

The most commonly used alternative to accelerate this process is Code Push which allows the application update without the need for a new deploy in the store. However in Code Push GitHub itself there is a Code Push Support for Flutter request with comment saying that support depends on implementing dynamic update support in Flutter, there is also a reference to Flutter Roadmap saying that support for This type of update is postponed according to the official comment Code Push / Hot Update / out of band updates, which explains the reasons that led to the decision.

One possible solution to this deadlock is to implement a JSON interpreter that enables screen redesign, which can be obtained using dynamic_widget. Although dynamic_widget provides an easy way to extend support for other widgets through separate implementations. It limits the use of events and does not allow the use of complex business rules.

How this work

The basic operation of schema_widget is very similar to that of dynamic_widget. Both interpret JSON and instantiate the widget for it. The main difference with schema_widget is that it allows the creation of parsers for any type of object and the use of pre-implemented rules. For this reason, it makes it possible to create much more complex business rules.

The schema_widget package provides the SchemaWidget class, in most cases this will be the only class used. All methods in this class are static.

To add a new parser, the following methods can be used:

Default parsers: This method loads all the default parsers from schema_widget.

  SchemaWidget.registerParsers();

Synchronous: This method can be used to load a custom parser that can be loaded synchronously.

  TypeSchemaParser typeSchemaParserInstance = CustomTypeSchemaParser();

  SchemaWidget.registerTypeParser(typeSchemaParserInstance);

Asynchronous: This method can be used to load a custom parser that needs to be loaded asynchronously.

  String typeName = "Custom";
  Future<TypeSchemaParser> futureTypeSchemaParserInstance = () async => CustomTypeSchemaParser();

  SchemaWidget.registerTypeParserAsync(typeName, futureTypeSchemaParserInstance);

In addition to parsers, any type of function and object for use by parsers can also be registered. For this, the SchemaWidget.registerLogic(logicName, logic) method must be used. The logic name must be unique, otherwise the previously registered logic will be replaced.

Example:

  const string1 = "Hello World";
  const map1 = {"foo": "bar"};
  const object1 = Foo();
  var func1 = () => "Hello World";
  var asyncFunc1 = () async => "Hello World";
  var object2 = Bar();

  SchemaWidget.registerLogic("string1", string1);
  SchemaWidget.registerLogic("map1", map1);
  SchemaWidget.registerLogic("object1", object1);
  SchemaWidget.registerLogic("func1", func1);
  SchemaWidget.registerLogic("asyncFunc1", asyncFunc1);
  SchemaWidget.registerLogic("otherExemple", object2);

Both parsers and logics are registered using the get_it package to manage everything. After registering all the parsers and logic necessary for use. It may be necessary to wait for GetIt to finish loading asynchronous parsers. For this, GetIt makes GetIt.I.allReady() available for use in a FutureBuilder for the purpose of creating widgets only after all parsers are loaded as shown in the following example.

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key) {
    SchemaWidget.registerParsers();
    SchemaWidget.registerLogic("funcHelloWorld", () => Text("Hello World"));
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: GetIt.I.allReady(ignorePendingAsyncCreation: false),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }

        return SchemaWidget.parse<Widget>(
          context,
          {
            "type": "Scaffold",
            "appBar": {
              "type": "AppBar",
              "title": {
                "type": "Text",
                "data": "Hello World Example",
              },
            },
            "body": {
              "type": "Center",
              "child": "funcHelloWorld",
            },
          },
        );
      },
    );
  }
}

Alternatively, SchemaWidget itself can be used to execute SchemaWidget.registerParsers() and SchemaWidget.parse<Widget>(), reducing the complexity of the code.

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key) {
    SchemaWidget.registerLogic("funcHelloWorld", () => Text("Hello World"));
  }

  @override
  Widget build(BuildContext context) {
    return SchemaWidget(
      {
        "type": "Scaffold",
        "appBar": {
          "type": "AppBar",
          "title": {
            "type": "Text",
            "data": "Hello World Example",
          },
        },
        "body": {
          "type": "Center",
          "child": "funcHelloWorld",
        },
      },
    );
  }
}

TypeSchemaParser

Everything in schema_widget is based on TypeSchemaParser.

TypeSchemaParser is the implementation of a JSON interpreter that converts it into a complex object.

Getting Started

  • For help over SchemaWidget usage, view the example;
  • For help over class documentation, view the documentation;
  • For help getting started with Flutter, view our online documentation;
  • For help on editing package code, view the documentation.

Installation

  • Add this to your package's pubspec.yaml file:
dependencies:
  get_it:
  schema_widget: ^2.0.0-beta.0
  • Install packages from the command line: with Flutter:
$ flutter packages get
  • Import it into the code file:
 import 'package:schema_widget/schema_widget.dart';

Usage

import 'dart:async';

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

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

class MyApp extends StatelessWidget {
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  MyApp({Key key}) : super(key: key) {
    SchemaWidget.registerLogic(
      "onGenerateRoute",
      _onGenerateRoute,
    );
    SchemaWidget.registerLogic(
      "onUnknownRoute",
      _onUnknownRoute,
    );
    SchemaWidget.registerLogic(
      "navigatorKey",
      _navigatorKey,
    );
  }

  @override
  Widget build(BuildContext context) {
    return SchemaWidget(
      loadSchemas: false,
      {
        "type": "MaterialApp",
        "title": 'SchemaWidget Demo',
        "theme": {
          "primarySwatch": {
            "primary": 0xFF2196F3,
            "swatch": {
              "50": 0xFFE3F2FD,
              "100": 0xFFBBDEFB,
              "200": 0xFF90CAF9,
              "300": 0xFF64B5F6,
              "400": 0xFF42A5F5,
              "500": 0xFF2196F3,
              "600": 0xFF1E88E5,
              "700": 0xFF1976D2,
              "800": 0xFF1565C0,
              "900": 0xFF0D47A1,
            },
          },
        },
        "navigatorKey": "navigatorKey",
        "initialRoute": "home",
        "onGenerateRoute": "onGenerateRoute",
        "onUnknownRoute": "onUnknownRoute"
      },
    );
  }

  Route _onGenerateRoute(RouteSettings settings) {
    return MaterialPageRoute(
      builder: (buildContext) => MyHomePage(),
      settings: settings,
    );
  }

  Route _onUnknownRoute(RouteSettings settings) {
    return MaterialPageRoute(
      builder: (buildContext) => MyHomePage(),
      settings: settings.copyWith(name: "home"),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key) {
    SchemaWidget.registerLogic("funcHelloWorld", () => Text("Hello World"));
  }

  @override
  Widget build(BuildContext context) {
    return SchemaWidget(
      {
        "type": "Scaffold",
        "appBar": {
          "type": "AppBar",
          "title": {
            "type": "Text",
            "data": "Hello World Example",
          },
        },
        "body": {
          "type": "Center",
          "child": "funcHelloWorld",
        },
      },
    );
  }
}

Next steps

  • Publish Package;
  • Make MVP;
  • Minimal documentation;
  • Change event binding of click event;
  • Add list of default supported Widgets;
  • Add list of default supported Types;
  • Create content about;
  • Publish complementar packages;
  • Create example full functional apps;
  • Make a commercial product using the package;

schema_widget's People

Contributors

mend-bolt-for-github[bot] avatar windol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

schema_widget's Issues

[DepShield] (CVSS 7.4) Vulnerability due to usage of lodash._reinterpolate:3.0.0

Vulnerabilities

DepShield reports that this application's usage of lodash._reinterpolate:3.0.0 results in the following vulnerability(s):


Occurrences

lodash._reinterpolate:3.0.0 is a transitive dependency introduced by the following direct dependency(s):

standard-version:8.0.2
        └─ conventional-recommended-bump:6.0.9
              └─ git-raw-commits:2.0.0
                    └─ lodash.template:4.5.0
                          └─ lodash._reinterpolate:3.0.0
                          └─ lodash.templatesettings:4.2.0
                                └─ lodash._reinterpolate:3.0.0

This is an automated GitHub Issue created by Sonatype DepShield. Details on managing GitHub Apps, including DepShield, are available for personal and organization accounts. Please submit questions or feedback about DepShield to the Sonatype DepShield Community.

[DepShield] (CVSS 7.5) Vulnerability due to usage of q:1.5.1

Vulnerabilities

DepShield reports that this application's usage of q:1.5.1 results in the following vulnerability(s):


Occurrences

q:1.5.1 is a transitive dependency introduced by the following direct dependency(s):

standard-version:8.0.2
        └─ conventional-changelog:3.1.21
              └─ conventional-changelog-angular:5.0.11
                    └─ q:1.5.1
              └─ conventional-changelog-atom:2.0.7
                    └─ q:1.5.1
              └─ conventional-changelog-codemirror:2.0.7
                    └─ q:1.5.1
              └─ conventional-changelog-conventionalcommits:4.3.1
                    └─ q:1.5.1
              └─ conventional-changelog-core:4.1.8
                    └─ q:1.5.1
              └─ conventional-changelog-ember:2.0.8
                    └─ q:1.5.1
              └─ conventional-changelog-eslint:3.0.8
                    └─ q:1.5.1
              └─ conventional-changelog-express:2.0.5
                    └─ q:1.5.1
              └─ conventional-changelog-jquery:3.0.10
                    └─ q:1.5.1
              └─ conventional-changelog-jshint:2.0.8
                    └─ q:1.5.1
        └─ conventional-recommended-bump:6.0.9
              └─ q:1.5.1
        └─ conventional-changelog-conventionalcommits:4.3.0
              └─ q:1.5.1

This is an automated GitHub Issue created by Sonatype DepShield. Details on managing GitHub Apps, including DepShield, are available for personal and organization accounts. Please submit questions or feedback about DepShield to the Sonatype DepShield Community.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.