Flutter 离线数据方案 Flutter_Data 包

news2025/1/17 0:03:41

Flutter 离线数据方案 Flutter_Data 包

alt

原文 https://levelup.gitconnected.com/flutter-offline-first-with-flutter-data-62bad61097be

前言

alt

通过离线优先来改善您的用户体验

Flutter Data 是一个让你的应用程序先离线的软件包。

离线时,它在设备上使用 Hive 存储,当到 API 的连接可用时,更改将自动同步。

在本文中,我们将添加 flutter_data 包并将其连接起来,以便在应用程序启动时检索 recipes。

正文

我花了一段时间才弄清楚自己想要什么,并勾勒出设计草图:

High level design
High level design

High level design

当时发生了很多事情,要想做好是很复杂的。

我用粗体文本突出显示了一些需要编码或配置的操作,并用它们制作了一个任务列表:

  • 步骤 1: 在启动时从 app_config.json 加载环境值。
  • 步骤 2: 添加新包。
  • 步骤 3: 注释 recipes 模型。
  • 步骤 4: 配置 Flutter 数据。
  • 步骤 5: 覆盖 Http 客户端使用 Dio。
  • 步骤 6: 为开发和测试配置 Mock Adapter。

您可以在 XP 部分中找到实现细节。

这篇文章有很多细节,我的建议是阅读足够多的内容来理解正在发生的事情,如果您决定或需要实现它,可以将其作为参考。

请反馈,如果你有更好的方法或建议的改进。我们欢迎任何有助于改进这一关键发展任务的帮助。

Ta Da 哒哒

GlobalEnvironmentValues.instance
   .loadValues(await rootBundle.loadString("app_config.json"));
Load the environment values from app_config.json on startup.
Load the environment values from app_config.json on startup.

启动时从 app_config.json 加载环境值。

Using the mocked API client for requests
Using the mocked API client for requests

对请求使用模拟 API 客户端

Flutter Data triggering FindAll method for recipes
Flutter Data triggering FindAll method for recipes

Flutter 数据触发 FindAll 方法

Display the recipes returned
Display the recipes returned

显示返回的 recipes

Displaying recipes returned by Flutter Data
Displaying recipes returned by Flutter Data

显示 Flutter Data 返回的 recipes

感觉有点虎头蛇尾,因为我们刚刚配置了离线访问,但仍在使用模拟数据进行开发和测试。

但是,这是我们现在可以支持新实体的离线数据的一大步,我们已经为关键的开发任务(添加或修改特性)准备了强大的编码模式。

一旦我进行了身份验证,我就会回来,使 Flutter Data 能够使用基于环境的云 API 服务,我希望设置 dev_online 和 dev_local 模式,并使用部署构建来配置 UAT 和 Live 版本。

实施细节

  • 步骤 1 ー在启动时加载环境值
Load environment values from app_config.json file
Load environment values from app_config.json file

从 app_config.json 文件加载环境值

“GlobalEnvironmentValues”服务使用“ EnvConfigReader”加载 app_config.json 值:

import 'dart:convert';


// Access to enviromental values that are loaded from a config file.

// The CI/CD injects the per environment files on deployment.

class EnvConfigReader {

  late Map<Stringdynamic> _config;


  EnvConfigReader(String configFileJson) {

    _config = json.decode(configFileJson) as Map<Stringdynamic>;

  }


  String value(String key) {

    return _config[key];

  }

}
  • 步骤 2 ーー添加新的软件包
# Offline-first data framework with a customizable REST client and powerful model relationships.

flutter_data: ^1.4.7


# A reactive state caching and data-binding framework

# Recommend replacement for provider: that is mentioned by flutter

# https://docs.flutter.dev/development/data-and-backend/state-mgmt/options

hooks_riverpod: ^1.0.3+1


# Annotations used by code gen to create code for JSON serialization and deserialization

json_annotation: ^4.7.0


# Generate to/from JSON code for a class

json_serializable: ^6.5.4

步骤 3 ーー注释 recipes 模型

import 'package:flutter_data/flutter_data.dart';

import 'package:json_annotation/json_annotation.dart';

import 'package:simbucore/app/mixin/flutter_data_dev_api_server_adapter.dart';


part 'recipe.g.dart';


@JsonSerializable()

@DataRepository([FlutterDataApiServerAdapter])

class Recipe extends DataModel<Recipe{

  @override

  final int? id;

  final String title;

  final String link;

  final String source;

  final String totalTime;

  final HasMany<Ingredient> ingredients;

  final HasMany<Step> steps;

  final String thumbnail;

将零件引用添加到将要生成的文件的导入,在下一步运行构建器之前,您将看到一个错误:

Missing file error
Missing file error

文件丢失错误

关系需要使用 HasMany 和 BelongsTo 查看更多信息的文档。

Mixin FlutterDataApiServerAdapter 使用我们现在在启动时加载的环境值设置 API 基 URL。

alt
  • 步骤 4 ー设定 Flutter 数据

生成配方库

flutter pub run build_runner build

我们需要生成一个存储库,然后才能在启动时初始化它,因为代码生成会在它生成的文件中生成初始化方法:

alt
File generated by Flutter Data (Hive)
File generated by Flutter Data (Hive)

由 Flutter 数据生成的文件(Hive)

现在我们可以在应用程序启动时将其连接起来:

Wire up the local Hive storage
Wire up the local Hive storage

Wire up the local Hive storage

连接本地的 Hive 仓库

  • 步骤 X ー模拟 API 回应

这个重新设计的步骤 X ーー Mock API Response,现在取代了计划中的两个步骤:

  • 步骤 5 ーー重写 Http 客户端以使用 Dio
  • 步骤 6 ー配置模拟适配器

在对 Flutter Data 代码进行了更深入的研究之后,很明显,尝试使用 Dio 将意味着与包对抗,很多好处都在于它使用的针对 watch One、 Save、 findAll 等方法的代码中。

通过研究 Flutter Data 如何测试它拥有的代码并决定重写 HttpClient,我找到了我需要的东西:

Overide HttpClient provider to mock API responses
Overide HttpClient provider to mock API responses

重写 HttpClient 提供程序以模拟 API 响应

Dio 还会带来其他一些好处,但是看起来 Flutter Data 可以通过自定义适配器轻松 extension ,以处理身份验证令牌和重试之类的事情。在 Flutter Data 网站上有一些文章和代码示例。

为什么我选择使用 Flutter_Data

使用包是简化和减少项目代码的一种很好的方法,使其更容易维护。

我们在引入微应用程序 DigestablePrologue 时看到了这一点,它允许我删除主项目 DigestableMe 中的横切代码。

这简化了 DigestableMe 中的代码,让它专注于应用程序的特性,而 DigestablePrologue 处理所有的启动操作,比如布局和主题选择,以及连接 Riverpod 的 state management 包。

但是没有什么是 free 的,软件包会限制你,它们可能会停滞不前,或者会导致破坏性的变化,有依赖性,把你绑定到旧的软件包,有 bug 或者漏洞百出的抽象。

我的引爆流行是,Flutter_data 提供了大量我正在寻找的功能,与 Riverpod 非常契合:

  • 使用代码生成从带注释的类创建 CRUD 存储库。
  • 建立本地数据库。
  • 离线检测。
  • 反应式数据绑定。
  • 失败和重试处理。
  • 在线时与 RestAPI 自动同步。
  • 可交换的关系。
  • 和 Riverpod 一起工作。
  • 支持我想使用的 JSON: API。
  • JSON 序列化被加入进来。
  • 选项用于实现不可变性。

这是我们可以抽象出来的很多东西,我们可以创建一个新的规程来展示如何通过代码生成将新条目引入到应用程序中。

固执己见可以成为团队中真正的力量,如何达成共识是困难的一点,它通常涉及到更密切的合作。

多年来,我发现结对编程在组建团队和开始项目时确实很有帮助。

Going in the same direction
Going in the same direction

Going in the same direction

朝着同一个方向

每个环境的 API’s

将文件添加到项目 app_config 的根目录。Json 来保存开发 api 端点地址,这将被 CodeMagic 构建来支持其他环境所吞噬,详情请参阅他们的文章《带有 CodeMagic CD 的 Flutter 环境》。

然后拦截这个虚构的端点,指向我们的模拟开发数据。

Development environment config values
Development environment config values

开发环境配置值

这些值可以通过提供程序访问,提供程序在应用程序运行时读取这些值。

灵活的学习和实验

在上一篇文章中,我添加了一个特性来检测客户机设备何时脱机,目的是使用它来同步脱机数据。

当我在本文中介绍 Flutter_Data 时,我意识到它可以处理检测,并且可以节省一些时间。然而:

你不能把未来的点点滴滴联系起来,你只能把它们回顾地联系起来... ..。

史蒂夫 · 乔布斯

它只是提醒我去尝试,但不要太珍惜扔掉我花时间在上面的工作,当一个更好的选择出现的时候。

Flutter Data ーー 关系

构建器强制要求图表中的所有相关模型都要注释:

Builder error - missing related ingredients model
Builder error - missing related ingredients model

生成器错误ーー缺少相关成分模型

Flutter Data ーー IsOfflineError 标志

How Flutter Data decides if a device is offline.
How Flutter Data decides if a device is offline.

Flutter Data 如何决定设备是否脱机。

Hive 本地数据库文件

Hive 在这里编写本地数据库文件:

/Users/<user>/Library/Developer/CoreSimulator/Devices
/060DB285-2820-411B-B5F7-76F9739DA934/data/Containers/Data/Application
/A72C3081-43DD-4E03-82D0-DC49A3AF1317/Documents/flutter_data

基本目录是通过路径提供程序包中的 getApplicationDocumentsDirectory 函数获得的,您可以在生成的 main.data.dart 文件中找到代码。

...
if (!kIsWeb) {
    baseDirFn ??= () => getApplicationDocumentsDirectory()
    .then(
      (dir) => dir.path
      );
  } else {
    baseDirFn ??= () => '';
  }
...

如果在 configureRepositoryLocalStorage 初始化方法中重写 baseDirFn 参数,则可以设置自己的基目录。

进入 external 包代码

为了找到 Hive 没有写入权限的目录路径,我必须打开调试包代码的能力

Code.Preferences.Settings menu item
Code.Preferences.Settings menu item

Code.Preferences.Settings 菜单项

我重新启动了 VisualStudio 代码以使其正常工作,但您可能只需要重新启动应用程序。

Flutter Data 数据诊断

我希望能够打开诊断日志记录,输出 Flutter Data 正在采取的关键操作,比如从 Hive 检索,因为离线并输出任何异常的信息,特别是从/到 json 的映射。

Discipline & Scaffold 脚手架

一旦我已经验证和使用 Flutter 数据的行动几次,我将创建一个新的纪律,围绕它和改善脚手架。

这将是大多数新特性的核心部分,值得努力使过程简单并且代码可维护。

Latency and Chat 延迟和聊天

如果我们遇到了响应问题,我们可能需要考虑减少对 API 的调用(少聊天) ,我怀疑这只是通过一个更大的图表或批处理调用,我们需要找出最好的方式,这将适合 flutter_data 包。

包和依赖项

在介绍了 Flutter_data 软件包之后,我试图将 Riverpod 升级到 2.1.1 版本,得到了以下结果:

Dependency conflict whilst upgrading Riverpod
Dependency conflict whilst upgrading Riverpod

依赖冲突同时升级 Riverpod

随着添加更多的软件包和微应用程序软件包,您的依赖关系将变得更难处理和升级。

这是一个候选的一些额外的报告或工具,以帮助我们的规模。

在这种情况下,Flutter_Data 需要 Riverpod 的 1.x 版本。

我在 pubspec.yaml 中为 Riverpod 指定了一些更高的版本号,在 simbucore 包中指定了 Flutter_Data,这简化了错误消息,从而解决了这个问题。

Clearer message
Clearer message

Clearer message

运行命令:

flutter pub outdated

显示可以解析的版本:

command output, showing the version that can be resolved
command output, showing the version that can be resolved

命令输出,显示可以解析的版本

Packages

  • Flutter_data
  • json_annotation
  • json_serializable

结束语

如果本文对你有帮助,请转发让更多的朋友阅读。

也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。

祝你有一个美好的一天~


© 猫哥

  • 微信 ducafecat

  • https://wiki.ducafecat.tech

  • https://video.ducafecat.tech

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DirectX12 - Triangle Culling and Winding Order(三角形的剔除与绕序)

这里是SunshineBooming&#xff0c;GPU公司一枚小小的Driver工程师&#xff0c;主要工作是写DirectX12 Driver&#xff0c;我会持续更新这个DX12 Spec系列&#xff0c;可能比较冷门&#xff0c;但是都是干货和工作中的心得体会&#xff0c;有任何GPU相关的问题都可以在评论区互…

Chapter9.2:线性系统的状态空间分析与综合(下)

此系列属于胡寿松《自动控制原理题海与考研指导》(第三版)习题精选&#xff0c;仅包含部分经典习题&#xff0c;需要完整版习题答案请自行查找&#xff0c;本系列属于知识点巩固部分&#xff0c;搭配如下几个系列进行学习&#xff0c;可用于期末考试和考研复习。 自动控制原理(…

GJB 5000B二级-LD领导作用

概要:GJB 5000B将GJB 5000A三级中的LD领导作用划分为二级内容,将组织类目标下沉至二级 借鉴GJB 9001C中的领导作用,结合各个行业优秀的实践,将5000A中的共用目标、实践进行了提炼、总结最终形成GJB 5000B中的领导作用实践域。 目的:进一步强化上层的领导作用,由高层、中层…

DOPE修饰岩藻多糖 Fucoidan-DOPE 岩藻多糖-二油酰基磷脂酰乙醇胺

DOPE修饰岩藻多糖 Fucoidan-DOPE 岩藻多糖-二油酰基磷脂酰乙醇胺 中文名称&#xff1a;岩藻多糖-二油酰基磷脂酰乙醇胺 英文名称&#xff1a;Fucoidan-DOPE 别称&#xff1a;DOPE修饰岩藻多糖&#xff0c;DOPE-岩藻多糖 外观:固体或粘性液体&#xff0c;取决于分子量 PEG分…

天问一号(Tianwen-1)详细介绍

天问一号&#xff08;Tianwen-1&#xff09;是中国第二个火星探测项目。2020年4月24日&#xff0c;中国行星探测任务被命名为“天问系列”&#xff0c;火星探测任务被命名为天问一号&#xff0c;后续行星探测任务依次编号。中国首次火星探测任务标识为“揽星九天”。 火星探测任…

基于stm32的智能药盒

提示&#xff1a;记录2022年4月做的毕设 文章目录前言一、任务书1.1设计(研究)目标:1.2设计(研究)内容:二、框架思路三、硬件四、联系我们五、相关功能介绍六、喜欢请点赞哦&#xff01;前言 基于STM32的智能药盒&#xff0c;主控使用STM32F103&#xff08;正点原子战舰板子&a…

word 中添加图片目录、内部链接

目录1. 图片、表格添加目录1.1 插入题注1.2 添加目录2. 添加内部链接1. 图片、表格添加目录 1.1 插入题注 只有正确地插入题注&#xff0c;图表目录才能快速生成。 &#xff08;1&#xff09;两个方法调用“题注”功能&#xff08;任选1个&#xff09; 方法一&#xff1a;在菜…

【论文阅读 ICTIR‘2022】Revisiting Open Domain Query Facet Extraction and Generation

文章目录Revisiting Open Domain Query Facet Extraction and GenerationMotivationContributionsMethodFacet Extraction and GenerationFacet Extraction as Sequence LabelingAutoregressive Facet GenerationFacet Generation as Extreme Multi-Label ClassificationFacet …

【Pandas数据处理100例】(九十八):Pandas使用between_time()筛选出给定时间区间的数据

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

影响工业产品设计的主要因素

设计师对工业产品的产品外观设计主要依靠形状、图案和颜色的结合&#xff0c;创造出具有一定功能性质的新产品。在这个过程中&#xff0c;设计师需要充分利用各种因素&#xff0c;外观工业设计公司强调材料的机制和颜色。那么&#xff0c;影响产品设计的主要因素是什么呢? 一、…

IMMA~~

搬来自斯坦福的研究者提出了 IMMA, 一种利用隐空间多层图 (multiplex latent graphs) 来表征多种独立的交互类型&#xff0c;并使用一种新型的多层图注意力机制 (multiplex attention mechanism) 来描述个体间交互强度的行为及轨迹预测模型。该方法不仅大幅提升了预测的准确度&…

中小企业如何进行云灾备?

随着IT服务在企业运营和运维的影响权重日益增强&#xff0c;企业IT投入也越来越高&#xff0c;而随着云计算的逐步渗透&#xff0c;企业们逐渐将本地数据迁移到云上&#xff0c;以节省本地服务器的部署与运维等成本。如雨后新笋般冒出的中小企业&#xff0c;难以负荷高成本的本…

从 select、poll、epoll 回答IO多路复用

前言 先大概了解一下这方面的知识 IO多路复用指的是单个进程或者线程能同时监听处理多个IO请求&#xff0c; select、epoll、poll是LinuxAPI提供的复用方式。本质上是由操作系统内核缓存fd文件描述符&#xff0c; 使得单个进程线程能监视多个文件描述符。 select是将所有文件…

Spire.PDF 8.11.10 supports .NET 7.0 and PDF to PPTX

度娘找破解版Spire.PDF for .NET is a professional PDF API applied to creating, writing, editing, handling and reading PDF files without any external dependencies within .NET ( C#, VB.NET, ASP.NET, .NET Core, .NET 5.0, .NET 6.0, MonoAndroid and Xamarin.iOS )…

如何在表格里面添加表单,并且进行表单验证

通过el-form和el-table的组合使用,在表格里面添加表单 并且进行验证 表单中v-model绑定scope.row中表格的数据 效果如图所示: <template><div><!-- <el-form ref"ruleForm" :model"ruleForm" :rules"rules"><el-form-…

C++ 类的静态成员详解【static】

目录 前言 一、类的静态成员 1.static关键字 2.静态成员变量 3.静态成员函数 二、程序样例 1.程序演示 2.程序截图 总结 前言 本文记录C中 static 修饰类成员成为静态成员&#xff0c;其中包括静态成员类别、作用和程序演示。 嫌文字啰嗦的可直接跳到最后的总结。 一、类的静…

从爆红到被黑,游戏黑产攻防48小时

编者按&#xff1a; 数字化浪潮蓬勃兴起&#xff0c;企业面临的安全挑战亦日益严峻。 腾讯安全近期将复盘2022年典型的攻击事件&#xff0c;帮助企业深入了解攻击手法和应对措施&#xff0c;完善自身安全防御体系。 本篇聚焦某游戏公司新游戏上线后与黑产多轮攻防的48小时里…

Python遥感开发之arcpy批量重采样

Python遥感开发之arcpy批量重采样1. 重采样2. ARCGIS中的重采样3. Python_arcpy代码实现前言&#xff1a;主要介绍使用ARCGIS中自带的重采样工具&#xff0c;以及Python代码实现arcpy批量重采样&#xff0c;使用Python代码更加方便快捷。1. 重采样 作用&#xff1a;更改栅格数…

百度飞桨公布最新成果:凝聚535万开发者,服务20万家企事业单位

11月30日&#xff0c;由深度学习技术及应用国家工程研究中心主办的WAVE SUMMIT2022深度学习开发者峰会如期而至。鹏城实验室主任、中国工程院高文院士&#xff0c;深圳大学电子与信息工程学院院长、深度学习技术及应用国家工程研究中心技术委员会副主任、中国工程院丁文华院士受…

【数据结构】二叉树详解(下篇)

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《数据结构》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 二叉树&…