Flutter网络请求与管理插件dash_kit_network的使用

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

Flutter网络请求与管理插件dash_kit_network的使用

Dash-Kit Networking

Dash-Kit Network 插件包含基于 Dio Http client 的 Http 请求 API,提供了处理网络功能的核心特性,包括令牌刷新。

安装

要在项目中使用此插件,请将 dash_kit_network 作为依赖项添加到您的 pubspec.yaml 文件中。

dependencies:
  dash_kit_network: ^latest_version

使用说明

1. 创建 Application Api 文件

首先,为项目创建一个 Application Api 文件以存储所有必要的 API 请求。该文件应扩展 ApiClient 组件。

import 'package:example/api/response_mappers.dart' as response_mappers;

class ApplicationApi extends ApiClient {
  ApplicationApi({
    required ApiEnvironment environment,
    required Dio dio,
  }) : super(environment: environment, dio: dio);
}

2. 初始化 Application Api 实例

接下来,在 main.dart 中使用 DioApp Environment 实例初始化 Application Api 实例,并将其传递给 Flutter 应用程序。

import 'package:dash_kit_network/dash_kit_network.dart';
import 'package:example/app.dart';
import 'package:flutter/material.dart';

import 'api/application_api.dart';

void main() {
  final dio = Dio();

  const apiEnvironment = ApiEnvironment(
    baseUrl: 'https://reqres.in/api/',
    validateRequestsByDefault: false,
    isRequestsAuthorisedByDefault: false,
  );

  final apiClient = ApplicationApi(
    dio: dio,
    environment: apiEnvironment,
  );

  dio.interceptors.add(LogInterceptor(
    request: true,
    requestBody: true,
    requestHeader: true,
    responseBody: true,
  ));

  runApp(MyApp(
    apiClient: apiClient,
  ));
}

3. 创建响应模型

为了将从网络响应(通常是 JSON 格式)接收到的数据转换为自定义 Dart 对象,需要创建相应的响应模型。可以使用 json_serializableFreezed 构建器来创建处理 JSON 数据的模型。

UserResponseModel 示例

part 'user_response_model.g.dart';

@JsonSerializable()
class UserResponseModel {
  UserResponseModel({
    required this.id,
    required this.email,
    required this.firstName,
    required this.lastName,
    required this.avatar,
  });

  factory UserResponseModel.fromJson(Map<String, dynamic> json) =>
      _$UserResponseModelFromJson(json);

  final int id;
  final String email;
  final String firstName;
  final String lastName;
  final String avatar;

  String get fullName => '$firstName $lastName';

  Map<String, dynamic> toJson() => _$UserResponseModelToJson(this);
}

UsersResponseModel 示例

part 'users_response_model.g.dart';

@JsonSerializable()
class UsersResponseModel {
  UsersResponseModel({
    required this.data,
  });

  factory UsersResponseModel.fromJson(Map<String, dynamic> json) =>
      _$UsersResponseModelFromJson(json);

  final List<UserResponseModel> data;

  Map<String, dynamic> toJson() => _$UsersResponseModelToJson(this);
}

4. 创建响应映射器

还需要创建响应映射器来处理请求完成后的数据。

UsersResponseModel users(Response response) {
  if (response.statusCode == 200) {
    return UsersResponseModel.fromJson(response.data);
  }

  throw ResponseErrorModel.fromJson(response.data);
}

5. 声明网络请求方法

在 Application Api 文件中声明所需的请求方法。这些方法应返回指定响应模型类型的 Feature,并使用以下之一的 API 方法:

  • get - 用于从指定资源请求数据
  • post - 用于向服务器发送数据以创建/更新资源
  • put - 用于向服务器发送数据以创建/更新资源(PUT 方法用于修改单个资源,而 POST 方法用于添加子资源)
  • patch - 用于部分更新资源
  • delete - 用于删除指定资源
  • updateAuthTokens - 使用令牌管理器更新令牌对
  • clearAuthTokens - 从令牌存储中移除令牌
  • isAuthorized - 通过检查令牌存储是否为空来验证用户是否已授权
import 'package:example/api/response_mappers.dart' as response_mappers;

class ApplicationApi extends ApiClient {
  ApplicationApi({
    required ApiEnvironment environment,
    required Dio dio,
  }) : super(environment: environment, dio: dio);

  Future<UsersResponseModel> getUserList() => get(
        path: 'users',
        responseMapper: response_mappers.users,
        validate: false,
        connectTimeout: 30,
        receiveTimeout: 30,
        sendTimeout: 30,
      );

  Future<LoginResponseModel> saveAuthTokens(LoginResponseModel response) {
    return updateAuthTokens(
      TokenPair(
        accessToken: response.accessToken,
        refreshToken: response.refreshToken,
      ),
    ).then((value) => response).onError((error, stackTrace) {
      print(error);
      return Future.error(error!);
    });
  }
}

6. 调用网络请求

最后,在应用程序中调用创建的网络请求。

class _MyHomePageState extends State<MyHomePage> {
  bool isLoading = false;
  StreamSubscription? subscription;
  List<UserResponseModel> users = [];

  @override
  void initState() {
    super.initState();
    _loadUserList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        child: isLoading ? _getProgressWidget() : getUsersWidget(users),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _loadUserList,
        tooltip: 'Load a user list',
        child: const Icon(Icons.update),
      ),
    );
  }

  Future<void> _loadUserList() async {
    subscription?.cancel();
    setState(() => isLoading = true);

    try {
      final response = await widget.apiClient.getUserList();
      users = response.data;
    } catch (e) {
      showErrorDialog();
    }

    setState(() => isLoading = false);
  }

  // ... 其他代码 ...
}

示例项目

您还可以查看 示例项目 获取更多详细信息。


更多关于Flutter网络请求与管理插件dash_kit_network的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络请求与管理插件dash_kit_network的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用dash_kit_network插件进行网络请求与管理的代码案例。请注意,dash_kit_network是一个假设的插件名称,因为在实际的Flutter插件生态系统中,并没有直接名为dash_kit_network的插件。不过,我可以根据常见的网络请求管理插件的功能来模拟一个示例。

假设dash_kit_network插件提供了基本的GET和POST请求方法,并且具有错误处理和请求取消的功能。以下是一个简单的使用示例:

1. 添加依赖

首先,在你的pubspec.yaml文件中添加dash_kit_network(这里假设它已经存在)的依赖:

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

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

2. 导入插件

在你的Dart文件中导入dash_kit_network插件:

import 'package:dash_kit_network/dash_kit_network.dart';

3. 配置网络请求

假设dash_kit_network插件提供了一个全局的配置类NetworkConfig,以及请求方法getpost

配置网络请求(假设)

void configureNetwork() {
  // 假设NetworkConfig是配置类
  NetworkConfig.instance.baseUrl = 'https://api.example.com';
  NetworkConfig.instance.timeout = Duration(seconds: 30);
  // 可以添加其他配置,如headers等
}

发起GET请求

Future<void> fetchData() async {
  try {
    // 发起GET请求
    var response = await NetworkService.get('/endpoint');
    if (response.isSuccessful) {
      // 处理成功响应
      print('Data: ${response.data}');
    } else {
      // 处理错误响应
      print('Error: ${response.errorMessage}');
    }
  } catch (error) {
    // 捕获并处理网络错误或取消请求等异常
    print('An error occurred: $error');
  }
}

发起POST请求

Future<void> submitData(Map<String, dynamic> payload) async {
  try {
    // 发起POST请求
    var response = await NetworkService.post('/endpoint', payload);
    if (response.isSuccessful) {
      // 处理成功响应
      print('Success: ${response.data}');
    } else {
      // 处理错误响应
      print('Error: ${response.errorMessage}');
    }
  } catch (error) {
    // 捕获并处理网络错误或取消请求等异常
    print('An error occurred: $error');
  }
}

4. 取消请求(假设)

假设dash_kit_network提供了取消请求的功能,我们可以使用CancelToken来实现:

import 'package:cancel_token/cancel_token.dart';  // 假设使用了cancel_token库

CancelToken cancelToken = CancelToken();

Future<void> fetchDataWithCancel() async {
  try {
    // 发起带有取消功能的GET请求
    var response = await NetworkService.get('/endpoint', cancelToken: cancelToken);
    if (response.isSuccessful) {
      // 处理成功响应
      print('Data: ${response.data}');
    } else {
      // 处理错误响应
      print('Error: ${response.errorMessage}');
    }
  } catch (error) {
    // 捕获并处理网络错误或取消请求等异常
    if (error is CancelError) {
      print('Request was canceled');
    } else {
      print('An error occurred: $error');
    }
  }
}

// 在需要取消请求的地方调用
void cancelRequest() {
  cancelToken.cancel('Request was canceled by user');
}

5. 完整示例

将上述代码整合到一个完整的示例中:

import 'package:flutter/material.dart';
import 'package:dash_kit_network/dash_kit_network.dart';
import 'package:cancel_token/cancel_token.dart';

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

void configureNetwork() {
  NetworkConfig.instance.baseUrl = 'https://api.example.com';
  NetworkConfig.instance.timeout = Duration(seconds: 30);
}

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  CancelToken cancelToken = CancelToken();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DashKit Network Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                fetchData();
              },
              child: Text('Fetch Data'),
            ),
            ElevatedButton(
              onPressed: () {
                fetchDataWithCancel();
              },
              child: Text('Fetch Data with Cancel'),
            ),
            ElevatedButton(
              onPressed: () {
                cancelRequest();
              },
              child: Text('Cancel Request'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> fetchData() async {
    try {
      var response = await NetworkService.get('/endpoint');
      if (response.isSuccessful) {
        print('Data: ${response.data}');
      } else {
        print('Error: ${response.errorMessage}');
      }
    } catch (error) {
      print('An error occurred: $error');
    }
  }

  Future<void> fetchDataWithCancel() async {
    try {
      var response = await NetworkService.get('/endpoint', cancelToken: cancelToken);
      if (response.isSuccessful) {
        print('Data: ${response.data}');
      } else {
        print('Error: ${response.errorMessage}');
      }
    } catch (error) {
      if (error is CancelError) {
        print('Request was canceled');
      } else {
        print('An error occurred: $error');
      }
    }
  }

  void cancelRequest() {
    cancelToken.cancel('Request was canceled by user');
  }
}

请注意,由于dash_kit_network是一个假设的插件,上述代码中的类和方法(如NetworkConfig, NetworkService, CancelToken等)可能并不存在于实际的Flutter插件中。你需要根据实际的网络请求管理插件的API进行调整。常见的Flutter网络请求插件如dioretrofit等提供了类似的功能,你可以参考它们的文档进行实现。

回到顶部