Flutter数据管理与存储插件data_repository的使用

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

Flutter数据管理与存储插件data_repository的使用

data_repository 是一个用于Flutter的数据管理库,它可以帮助你管理和处理本地和远程API的访问。通过这个插件,你可以轻松地实现数据的缓存、网络请求的拦截以及数据的持久化存储。

特性

  • 支持本地和远程数据源的管理
  • 提供缓存机制,可以自定义缓存策略
  • 支持拦截器,可以在请求和响应时进行处理
  • 可以与依赖注入库(如GetIt)结合使用

开始使用

1. 定义本地和远程仓库

首先,你需要定义本地和远程仓库的实现。本地仓库负责管理和检索本地缓存数据,而远程仓库则负责从远程服务器获取数据。推荐使用 GetIt 来进行依赖注入。

import 'package:get_it/get_it.dart';
import 'package:data_repository/data_repository.dart';

// 注册本地仓库和远程仓库
GetIt.I.registerSingleton<LocalRepository>(HiveRepository());
GetIt.I.registerSingleton<RemoteRepository>(
    RemoteRepository(HttpApiProvider()));
2. 创建API服务类

接下来,创建一个API服务类,用于定义你的API请求。这个类中包含了所有与远程服务器交互的方法。

class PostApi {
  // 定义创建帖子的API请求
  ApiRequest<Post, Post> create(CreatePostDto body) {
    return ApiRequest<Post, Post>(
      baseUrl: 'https://api.example.com', // 基础URL
      path: '/posts', // API路径
      method: ApiMethods.post, // 请求方法
      body: body.toJson(), // 请求体
      dataKey: 'data', // 数据键
      error: ErrorDescription(), // 错误描述
      interceptors: [
        HeaderInterceptor({
          'Authorization': 'Bearer $token', // 认证头
          "Content-Type": "application/json", // 内容类型
          "Accept": "application/json", // 接受类型
        }),
        JsonInterceptor<ErrorModel>(DepartmentModels.factories), // JSON拦截器
        NetworkDurationInterceptor(), // 网络延迟拦截器
      ],
    );
  }
}
3. 创建仓库类并扩展 DataRepository

然后,创建一个仓库类并继承 DataRepository,在其中初始化本地和远程仓库的实现。

class PostRepository extends DataRepository {
  final _api = PostApi();

  // 构造函数中传入本地和远程仓库
  PostRepository()
      : super(GetIt.I<LocalRepository>(), GetIt.I<RemoteRepository>());

  // 创建帖子的异步方法
  Future<ApiResponse<Post, Post>> createPost(CreatePostDto body) async {
    return await handleRequest(_api.create(body));
  }

  // 获取帖子列表的异步方法,并设置缓存策略
  Future<ApiResponse<List<Post>, Post>> getPosts() async {
    return await handleRequest(
      _api.getPosts(),
      cache: CacheDescription('posts-list', lifeSpan: CacheDescription.oneMinute),
    );
  }
}
4. 在视图模型中使用仓库

你可以在视图模型中使用仓库来获取数据并管理状态。以下是一个简单的示例,展示了如何在视图模型中调用 createPost 方法。

void createPost() async {
  emit(state.loading()); // 发送加载状态

  // 调用仓库中的 createPost 方法
  final response = await _repository.createPost(CreatePostDto(
    title: state.title ?? '',
    content: state.content ?? '',
    image: state.image ?? '',
  ));

  if (response.isSuccessful) {
    emit(PostCreated('创建成功', state)); // 发送成功状态
  } else {
    emit(ErrorState(response.error as ApiError, state)); // 发送错误状态
  }
}
5. 缓存机制

在仓库中,你可以通过设置 CacheDescription 来定义是否缓存请求结果。你可以指定缓存的键和生命周期。

Future<ApiResponse<List<Post>, Post>> getPosts() async {
  return await handleRequest(
    _api.getPosts(),
    cache: CacheDescription('posts-list', lifeSpan: CacheDescription.oneMinute),
  );
}
6. 拦截器

你可以定义拦截器来拦截请求或响应对象。拦截器可以在请求发送之前或响应返回之后执行某些操作。以下是一个简单的拦截器示例,用于记录网络请求的耗时。

class NetworkDurationInterceptor extends ApiInterceptor {
  Map<String, int> timestamp = {};

  [@override](/user/override)
  ApiResponse<ResponseType, InnerType> onResponse<ResponseType, InnerType>(
      ApiResponse<ResponseType, InnerType> response) {
    if (kDebugMode) {
      print(
          'NetworkDurationInterceptor ${response.statusCode}, ${response.request.requestId}, $timestamp ${timestamp[response.request.requestId]}');
    }

    var duration = DateTime.now().millisecondsSinceEpoch -
        (timestamp.remove(response.request.requestId) ?? 0);

    if (kDebugMode) {
      print('请求完成耗时 $duration 毫秒');
    }

    return response.copyWith(extra: {...?response.extra, 'duration': duration});
  }

  [@override](/user/override)
  ApiRequest<ResponseType, InnerType> onRequest<ResponseType, InnerType>(
      ApiRequest<ResponseType, InnerType> request) {
    timestamp
        .addAll({request.requestId: DateTime.now().millisecondsSinceEpoch});
    return request;
  }

  [@override](/user/override)
  ApiResponse<ResponseType, InnerType> onError<ResponseType, InnerType>(
      ApiResponse<ResponseType, InnerType> response) {
    var duration = DateTime.now().millisecondsSinceEpoch -
        (timestamp.remove(response.request.requestId) ?? 0);

    if (kDebugMode) {
      print('请求失败耗时 $duration 毫秒');
    }

    return response.copyWith(extra: {...?response.extra, 'duration': duration});
  }
}

示例应用

以下是一个完整的示例应用,展示了如何使用 data_repository 插件来管理数据。

import 'package:example/modules/post/views/post_screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dependency_injection.dart';

void main() async {
  await DependencyInjection.bootstrap(); // 初始化依赖注入
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Data Repository',
      theme: ThemeData(
        primarySwatch: Colors.deepOrange,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('示例')),
      body: ListView(children: [
        ListTile(
          title: const Text('帖子列表示例'),
          subtitle: const Text('获取帖子列表'),
          onTap: () => Navigator.push(
              context, CupertinoPageRoute(builder: (c) => const PostScreen())),
        )
      ]),
    );
  }
}

更多关于Flutter数据管理与存储插件data_repository的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据管理与存储插件data_repository的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用data_repository插件进行数据管理与存储的示例代码。需要注意的是,data_repository并不是一个官方或广泛认可的Flutter插件,因此这里假设它是一个自定义的或第三方数据管理与存储的库。为了示范,我们将模拟一个简单的数据仓库实现,这个仓库可以存储和检索用户信息。

1. 创建Flutter项目

首先,确保你已经安装了Flutter SDK,并创建了一个新的Flutter项目:

flutter create my_flutter_app
cd my_flutter_app

2. 添加依赖(假设data_repository是一个pub.dev上的包)

pubspec.yaml文件中添加data_repository(或任何实际使用的库)作为依赖:

dependencies:
  flutter:
    sdk: flutter
  data_repository: ^x.y.z  # 替换为实际版本号

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

3. 创建数据模型

创建一个简单的数据模型,例如User

// models/user.dart
class User {
  final String id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as String,
      name: json['name'] as String,
      email: json['email'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'email': email,
    };
  }
}

4. 实现数据仓库

这里我们模拟一个数据仓库,它可能基于SQLite、SharedPreferences或其他存储机制。由于data_repository的具体实现未知,我们将创建一个名为UserRepository的类来管理用户数据。

// repositories/user_repository.dart
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'models/user.dart';

class UserRepository {
  late Database _database;

  Future<void> init() async {
    _database = await openDatabase(
      (await getApplicationDocumentsDirectory()).path + 'users.db',
      version: 1,
      onCreate: (Database db, int version) async {
        await db.execute('''
          CREATE TABLE users (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            email TEXT NOT NULL
          )
        ''');
      },
    );
  }

  Future<User?> getUserById(String id) async {
    final List<Map<String, dynamic>> result = await _database.query('users', where: 'id = ?', whereArgs: [id]);
    if (result.isNotEmpty) {
      return User.fromJson(result.first);
    }
    return null;
  }

  Future<void> saveUser(User user) async {
    await _database.insert('users', user.toJson(), conflictAlgorithm: ConflictAlgorithm.replace);
  }

  Future<void> deleteUser(String id) async {
    await _database.delete('users', where: 'id = ?', whereArgs: [id]);
  }

  Future<List<User>> getAllUsers() async {
    final List<Map<String, dynamic>> result = await _database.query('users');
    return result.map((e) => User.fromJson(e)).toList();
  }
}

5. 使用数据仓库

在你的Flutter应用中,你可以这样使用UserRepository

// main.dart
import 'package:flutter/material.dart';
import 'repositories/user_repository.dart';
import 'models/user.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late UserRepository _userRepository;
  List<User> _users = [];

  @override
  void initState() {
    super.initState();
    _userRepository = UserRepository();
    _initializeApp();
  }

  Future<void> _initializeApp() async {
    await _userRepository.init();
    setState(() {
      _users = await _userRepository.getAllUsers();
    });
  }

  void _addUser() async {
    final User newUser = User(id: Uuid().v4(), name: 'John Doe', email: 'john.doe@example.com');
    await _userRepository.saveUser(newUser);
    setState(() {
      _users.add(newUser);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('User Management'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              Expanded(
                child: ListView.builder(
                  itemCount: _users.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(_users[index].name),
                      subtitle: Text(_users[index].email),
                    );
                  },
                ),
              ),
              ElevatedButton(
                onPressed: _addUser,
                child: Text('Add User'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意:上面的代码示例中,Uuid().v4()用于生成唯一的用户ID,你需要添加uuid: ^x.y.z到你的pubspec.yaml依赖中并运行flutter pub get来安装它。

结论

上面的代码展示了如何在Flutter应用中实现和使用一个简单的数据仓库来管理用户数据。虽然这里并没有直接使用一个名为data_repository的插件,但原理是相同的:定义一个数据模型,创建一个数据仓库类来管理数据的存储和检索,然后在你的Flutter应用中使用这个仓库。如果data_repository是一个具体的库,你应该参考它的文档来调整上述代码以适应其API。

回到顶部