Flutter离线优先与GraphQL集成插件brick_offline_first_with_graphql的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter离线优先与GraphQL集成插件brick_offline_first_with_graphql的使用

OfflineFirstWithGraphqlRepository 简化了 OfflineFirstRepository 与 GraphQL 的集成。它包含一个串行队列,用于在单独的 SQLite 数据库中跟踪 GraphQL 变更,只有在从主机接收到响应时(即设备失去互联网连接)才会移除请求。

OfflineFirstWithGraphql 域使用与 OfflineFirst 相同的所有配置和注解。

GraphqlOfflineQueueLink

为了缓存传出请求,可以在 GraphqlProvider 中应用 GraphqlOfflineQueueLink

GraphqlProvider(
  link: Link.from([
    GraphqlOfflineQueueLink(
      GraphqlRequestSqliteCacheManager('myAppRequestQueue.sqlite'),
      // 可选地指定队列重试和错误的回调函数
      onReattempt: onReattempt,
      onRequestException: onRequestException,
    ),
    HttpLink(endpoint)
  ]),
);

注意:确保将队列放置在 HttpLinkWebSocketLink 或任何其他传出 Link 之上。

模型

ConnectOfflineFirstWithGraphql

@ConnectOfflineFirstWithGraphql 装饰可以由 GraphQL 和 SQLite 序列化的模型。离线优先在类级别上没有配置,并且只扩展其提供程序持有的配置:

@ConnectOfflineFirstWithGraphql(
  graphqlConfig: GraphqlSerializable(),
  sqliteConfig: SqliteSerializable(),
)
class MyModel extends OfflineFirstModel {}

FAQ

为什么不能声明模型参数?

由于存在 一个未解决的分析器错误,自定义模型不能作为类型参数传递给存储库。

不支持的功能

字段类型

  • 来自 GraphqlProviderSqliteProvider 的任何不支持的字段类型。
  • 未来迭代器中的未来模型(例如 Future<List<Future<Model>>>

配置

  • <code>@OfflineFirst(where: 只支持极简单的重命名。多个 <code>where 键(例如 <code>OfflineFirst(where: {'id': 'data["id"]', 'otherVar': 'data["otherVar"]'}))或嵌套属性(例如 <code>OfflineFirst(where: {'id': 'data["subfield"]["id"]}))将被忽略。请确保使用 <code>@Graphql(name:) 来重命名生成的文档字段。

完整示例Demo

以下是一个完整的示例,展示了如何使用 brick_offline_first_with_graphql 插件来实现离线优先与 GraphQL 的集成:

import 'package:flutter/material.dart';
import 'package:brick_offline_first_with_graphql/graphQL_provider.dart';
import 'package:brick_offline_first_with_graphql/offline_first_model.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  [@override](/user/override)
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final endpoint = 'YOUR_GRAPHQL_ENDPOINT_HERE';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('离线优先与GraphQL集成示例'),
      ),
      body: Center(
        child: Text('加载数据...'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          // 初始化 GraphQL 提供程序
          await initGraphQL();
        },
        child: Icon(Icons.refresh),
      ),
    );
  }

  Future<void> initGraphQL() async {
    final client = GraphQLClient(
      cache: InMemoryCache(),
      link: Link.from([
        GraphqlOfflineQueueLink(
          GraphqlRequestSqliteCacheManager('myAppRequestQueue.sqlite'),
          // 可选地指定队列重试和错误的回调函数
          onReattempt: onReattempt,
          onRequestException: onRequestException,
        ),
        HttpLink(endpoint)
      ]),
    );

    final provider = GraphQLProvider(client: client);

    // 使用 GraphQL 提供程序
    runApp(
      ProviderScope(
        overrides: [
          graphqlClientProvider.overrideWithValue(client),
        ],
        child: MyApp(),
      ),
    );
  }

  void onReattempt(Request request, int attempts) {
    print('重试请求 $attempts 次');
  }

  void onRequestException(Object error, StackTrace stackTrace) {
    print('请求异常: $error');
  }
}

更多关于Flutter离线优先与GraphQL集成插件brick_offline_first_with_graphql的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter离线优先与GraphQL集成插件brick_offline_first_with_graphql的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成并使用brick_offline_first_with_graphql插件来实现离线优先和GraphQL支持的示例代码。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加brick_offline_first_with_graphql的依赖:

dependencies:
  flutter:
    sdk: flutter
  brick_offline_first_with_graphql: ^latest_version  # 请替换为实际最新版本号

然后运行flutter pub get来安装依赖。

2. 配置GraphQL客户端

你需要配置一个GraphQL客户端,这里我们使用graphql_flutter库。首先,添加graphql_flutter的依赖:

dependencies:
  graphql_flutter: ^latest_version  # 请替换为实际最新版本号

3. 设置离线优先的GraphQL客户端

在你的Flutter应用中,配置brick_offline_first_with_graphql插件来创建一个离线优先的GraphQL客户端。

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:brick_offline_first_with_graphql/brick_offline_first_with_graphql.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: GraphQLProvider(
        client: createOfflineFirstGraphQLClient(),
        child: MyHomePage(),
      ),
    );
  }

  ValueNotifier<GraphQLClient> createOfflineFirstGraphQLClient() {
    // 创建一个内存中的SQLite数据库来存储离线数据
    final storage = SQLiteStorage('offline_graphql_store.db');

    // 配置GraphQL客户端
    final httpLink = HttpLink({
      'uri': 'https://your-graphql-endpoint.com/graphql',  // 替换为你的GraphQL服务器URL
      'headers': <String, String>{
        'content-type': 'application/json',
        'authorization': 'Bearer YOUR_AUTH_TOKEN',  // 如果有认证token,请替换
      },
    });

    // 创建一个离线优先的GraphQL客户端
    final offlineLink = OfflineLink(
      storage: storage,
      networkLink: httpLink,
      retryLinkOptions: RetryLinkOptions(
        initialDelay: Duration(seconds: 1),
        maxAttempts: 5,
      ),
    );

    // 创建GraphQL客户端
    final client = GraphQLClient(
      cache: InMemoryCache(),
      link: offlineLink,
    );

    return ValueNotifier(client);
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final client = GraphQLProvider.of(context).value;

    // 示例查询
    final query = gql(`
      query GetUser($id: ID!) {
        user(id: $id) {
          id
          name
          email
        }
      }
    `);

    // 使用Query组件执行查询
    return Scaffold(
      appBar: AppBar(
        title: Text('Offline First GraphQL Example'),
      ),
      body: Query(
        query: query,
        variables: <String, dynamic>{'id': '1'},
        builder: (
          QueryResult result,
          {VoidFn? refetch, FetchMoreFn? fetchMore, RefetchFn? refetchVariables},
        ) {
          if (result.loading) {
            return Center(child: CircularProgressIndicator());
          }
          if (result.errors?.isNotEmpty ?? false) {
            return Center(child: Text('Error! ${result.errors![0].message}'));
          }
          if (result.data?.user != null) {
            final user = result.data!.user!;
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('ID: ${user.id}'),
                  Text('Name: ${user.name}'),
                  Text('Email: ${user.email}'),
                ],
              ),
            );
          }
          return Center(child: Text('No Data'));
        },
      ),
    );
  }
}

4. 运行应用

确保你已经配置好GraphQL服务器,并且服务器URL和认证信息是正确的。然后运行你的Flutter应用:

flutter run

注意事项

  • 替换https://your-graphql-endpoint.com/graphql为你的GraphQL服务器URL。
  • 如果你的GraphQL服务器需要认证,替换YOUR_AUTH_TOKEN为实际的认证Token。
  • 确保SQLite数据库文件路径和名称(offline_graphql_store.db)适合你的应用需求。

这个示例展示了如何使用brick_offline_first_with_graphql插件来创建一个离线优先的GraphQL客户端,并在Flutter应用中执行查询。你可以根据需要扩展这个示例,例如添加Mutation、Subscription等。

回到顶部