Flutter
GraphQL
在 Flutter 中实现离线优先 GraphQL 数据库
9 分
使用 graphql api 实现离线优先数据库 介绍 既然你在这里,你一定已经完成了其余的教程,并且熟悉执行 graphql 查询和变更以获取和修改数据。在本文件中,我们将探讨如何使用 flutter 和 graphql 实现离线优先用户界面。 目标 了解 flutter graphql 离线客户端的内部架构 允许应用程序即使在离线状态下也能运行 graphql 查询 实现离线数据持久性 先决条件 我们要求用户对 dart 和 flutter 有一些基本的了解。 虽然不是必要的,但 graphql 食谱将有助于理解一些 https //www back4app com/docs/parse graphql/graphql getting started 。 我们要求您已完成先决条件主题 https //www back4app com/docs/flutter/graphql/flutter graphql setup 并且之前已设置代码和实现 back4app 后端。 1 设置离线缓存 flutter graphql 客户端默认支持“离线查询”,即在离线状态下查询某些 graphql 数据时不会抛出错误,并会从缓存中获取数据。 我们必须注意,这与在应用程序会话之间持久化缓存不同,特别是 flutter graphql 客户端没有将缓存持久化到磁盘。因此,如果应用程序从系统托盘关闭并重新打开,数据仍然需要被获取。 要启用相同的功能,我们必须启用离线缓存: 转到 https //github com/templates back4app/flutter graphql/blob/772c058c74d870798af1cce7a29a5046f9dda456/lib/main dart#l32 1 return materialapp( 2 home graphqlprovider( 3 child cacheprovider( // cache provider widget that provides the offline queries support 4 child myhomepage(), 5 ), 6 client client, 7 ), 8 ); 2 设置存储偏好 使用 flutter graphql 客户端时有一个警告,即在应用程序关闭时,它不会存储任何自己的缓存,也不会在应用程序再次打开时填充缓存。 为了实现相同的功能,我们将利用 flutter shared preferences 库。它为简单数据(ios 和 macos 上的 nsuserdefaults,android 上的 sharedpreferences 等)包装了特定平台的持久存储,基本上允许以非常简单的方式离线存储数据。 要安装该库,请在 https //github com/templates back4app/flutter graphql/blob/772c058c74d870798af1cce7a29a5046f9dda456/pubspec yaml#l34 文件中添加 shared preferences ^ 0 5 12 + 4 在 https //github com/templates back4app/flutter graphql/blob/772c058c74d870798af1cce7a29a5046f9dda456/lib/main dart#l142 中添加以下内容 1 import 'package\ shared preferences/shared preferences dart'; 2 3 class sharedpreferenceshelper { 4 static final string offline cache key = 'programminglanguagelistresponse'; 5 6 static future\<programminglanguagelist> getcache() async { 7 final sharedpreferences prefs = await sharedpreferences getinstance(); 8 final cache = prefs getstring( offline cache key); 9 final offlinedata = 10 cache != null ? programminglanguagelistfromjson(cache) null; 11 12 return offlinedata; 13 } 14 15 static future\<bool> setcache(dynamic value) async { 16 final sharedpreferences prefs = await sharedpreferences getinstance(); 17 18 return prefs setstring( offline cache key, jsonencode(value)); 19 } 20 } 共享偏好库以键值形式存储数据,其中值被字符串化为 json 字符串。我们需要将这些数据解析为我们的数据模型。 3 解析本地存储的数据 我们将创建一个名为 programing languages model dart programing languages model dart 该文件将存储解析逻辑。我们将通过将我们的 graphql 响应粘贴到 https //app quicktype io/ 的 json 到 dart 模型转换器中来生成此逻辑。 我们将复制生成的代码并创建一个文件 programing languages model dart programing languages model dart https //github com/templates back4app/flutter graphql/blob/flutter graphql offline/lib/programing languages model dart 4 集成离线存储逻辑 如果数据不存在,我们将使用来自共享偏好的数据。如果数据也不在共享偏好中,我们将简单地显示一个加载图标。 我们现在将实施更改,以将所有更改集成在一起,在我们的 myhomepagestate myhomepagestate 的构建方法中,我们将更改我们的构建方法。我们将使用 futurebuilder futurebuilder 小部件来从 sharedpreferenceshelper 类中获取数据。 1 return futurebuilder\<programminglanguagelist>( 2 future sharedpreferenceshelper getcache(), 3 builder (prefs, snapshot) { 4 final offlinedata = snapshot data; 5 if (!snapshot haserror) { 6 return safearea( 7 … 使用 futurebuilder 小部件允许我们编写不需要使用状态的代码。从共享偏好中获取数据是一个相对快速的过程。在初始化共享偏好并从离线存储获取数据时,我们也可以显示一个加载器。 我们现在使用这个离线数据对象,并在 graphql 数据不可用时进行渲染。我们还将稍微重构代码。以下将是我们的代码: 查询 查询 https //github com/templates back4app/flutter graphql/blob/flutter graphql offline/lib/main dart 小部件。 1 body query( 2 options queryoptions( 3 documentnode gql(query), 4 ), 5 builder ( 6 queryresult result, { 7 refetch refetch, 8 fetchmore fetchmore, 9 }) { 10 final data = result data == null 11 ? offlinedata 12 programminglanguagelistfromjson( 13 jsonencode(result data)); 14 if (data == null) { 15 return center( 16 child text( 17 "loading ", 18 style textstyle(fontsize 20 0), 19 )); 20 } else { 21 sharedpreferenceshelper setcache(data); 22 return listview\ builder( 23 itembuilder (buildcontext context, int index) { 24 if (index == 0) { 25 return center( 26 child raisedbutton( 27 onpressed refetch, 28 child result loading == true 29 ? text("loading ") 30 text("refetch"), 31 ), 32 ); 33 } 34 return listtile( 35 title text(data programminglanguages 36 edges\[index 1] node name), 37 trailing text(data programminglanguages 38 edges\[index 1] node stronglytyped 39 ? "strongly typed" 40 "weekly typed"), 41 ); 42 }, 43 itemcount data programminglanguages edges length + 1, 44 ); 45 } 46 }, 47 ), 48 ), 我们应该得到以下内容: 结论 我们现在能够通过离线存储数据并在应用程序连接到互联网时重新验证数据,确保非常好的移动体验。此外,一个增强用户体验的重要方面是flutter graphql客户端缓存旧响应,并在发送新请求时自动进行。这使得我们不必在重新获取数据时不断显示笨拙的加载屏幕。 文章的代码可在以下地址找到: https //github com/templates back4app/flutter graphql/tree/flutter graphql offline