Flutter网络操作插件net_kit的使用

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

Flutter网络操作插件net_kit的使用

net_kit 是一个用于Flutter应用的网络操作插件,提供了多种功能来简化网络请求和处理。本文将详细介绍如何使用 net_kit 插件进行网络操作。

目录

特性

  • 自动刷新令牌
  • 使用 INetKitModel 解析响应为模型或模型列表
  • 可配置的开发和生产基础URL
  • 国际化错误消息支持
  • 认证支持(登录、注册、社交登录)

开始使用

初始化

首先,需要初始化 NetKitManager

import 'package:net_kit/net_kit.dart';

final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  devBaseUrl: 'https://dev.<URL>.com',
  // 其他参数
);

扩展模型

请求如 requestModelrequestList 需要模型扩展 INetKitModel 并实现 fromJsontoJson 方法:

class TodoModel extends INetKitModel {
  int? id;
  String? title;
  bool? completed;

  TodoModel({this.id, this.title, this.completed});

  [@override](/user/override)
  TodoModel fromJson(Map<String, dynamic> json) {
    return TodoModel(
      id: json['id'],
      title: json['title'],
      completed: json['completed'],
    );
  }

  [@override](/user/override)
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'completed': completed,
    };
  }
}

日志集成

可以创建一个类实现 INetKitLogger 接口来进行自定义日志记录:

final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  logger: NetworkLogger(),
  // 其他参数
);

发送请求

请求单个模型

Future<TodoModel> getTodo(int id) async {
  try {
    final result = await netKitManager.requestModel<TodoModel>(
      path: '/todos/$id',
      method: RequestMethod.get,
      model: TodoModel(),
    );
    return result;
  } on ApiException catch (e) {
    throw Exception(e.message);
  }
}

请求模型列表

Future<List<TodoModel>> getTodoList() async {
  try {
    final result = await netKitManager.requestList<TodoModel>(
      path: '/todos',
      method: RequestMethod.get,
      model: TodoModel(),
    );
    return result;
  } on ApiException catch (e) {
    throw Exception(e.message);
  }
}

发送空请求

Future<void> deleteTodoById(int id) async {
  try {
    await netKitManager.requestVoid(
      path: '/todos/$id',
      method: RequestMethod.delete,
    );
  } on ApiException catch (e) {
    throw Exception(e.message);
  }
}

认证方法

凭据登录

Future<UserModel> loginWithCredentials(SignInRequestModel signInRequest) async {
  try {
    final result = await netKitManager.authenticate<UserModel>(
      path: '/auth/signin',
      method: RequestMethod.post,
      model: UserModel(),
      body: signInRequest.toJson(),
    );

    final user = result.$1;
    final authToken = result.$2;

    print('User signed in: ${user.name}');
    print('Access token: ${authToken.accessToken}');

    return user;
  } catch (e) {
    throw Exception('Login failed: $e');
  }
}

注册

Future<UserModel> signUpUser(SignUpRequestModel signUpRequest) async {
  try {
    final result = await netKitManager.authenticate<UserModel>(
      path: '/auth/signup',
      method: RequestMethod.post,
      model: UserModel(),
      body: signUpRequest.toJson(),
    );

    final user = result.$1;
    final authToken = result.$2;

    print('User signed up: ${user.name}');
    print('Access token: ${authToken.accessToken}');

    return user;
  } catch (e) {
    throw Exception('Sign up failed: $e');
  }
}

社交账号登录

Future<UserModel> loginWithGoogle(String googleAccessToken) async {
  try {
    final result = await netKitManager.authenticate<UserModel>(
      path: '/auth/social-login',
      method: RequestMethod.post,
      model: UserModel(),
      socialAccessToken: googleAccessToken,
    );

    final user = result.$1;
    final authToken = result.$2;

    print('User signed in with Google: ${user.name}');
    print('Access token: ${authToken.accessToken}');

    return user;
  } catch (e) {
    throw Exception('Google login failed: $e');
  }
}

设置令牌

void setTokens(String accessToken, String refreshToken) {
  netKitManager.setAccessToken(accessToken);
  netKitManager.setRefreshToken(refreshToken);
}

用户登出

void logoutUser() {
  netKitManager.removeAccessToken();
  netKitManager.removeRefreshToken();
}

刷新令牌

刷新令牌初始化

final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  devBaseUrl: 'https://dev.<URL>.com',
  loggerEnabled: true,
  testMode: true,
  refreshTokenPath: '/auth/refresh-token',
  onTokenRefreshed: (authToken) async {
    /// Save the new access token to the storage
  },
  // 其他参数
);

刷新令牌示例

请参考上述代码段中的 refreshTokenPathonTokenRefreshed 参数。

刷新令牌的工作原理

当访问令牌过期时,NetKitManager 会自动检测并刷新令牌,确保无缝且不间断的API请求。

示例 Demo

以下是一个完整的示例Demo,展示了如何使用 net_kit 进行基本的CRUD操作:

import 'package:net_kit/net_kit.dart';
import 'core/logger/network_logger.dart';
import 'models/todo_model.dart';

void main() {
  final netKitManager = NetKitManager(
    baseUrl: 'https://jsonplaceholder.typicode.com',
  );

  const logger = NetworkLogger();

  TodoRemoteDataSourceImpl(netKitManager: netKitManager, logger: logger)
    ..getTodoList()
    ..getTodo(1)
    ..createTodo(TodoModel(id: 1, title: 'Test', userId: 1, completed: false))
    ..deleteTodoById(1);
}

abstract class TodoRemoteDataSource {
  Future<void> deleteTodoById(int id);
  Future<void> getTodoList();
  Future<void> getTodo(int id);
  Future<void> createTodo(TodoModel todo);
}

class TodoRemoteDataSourceImpl extends TodoRemoteDataSource {
  TodoRemoteDataSourceImpl({
    required INetKitManager netKitManager,
    required INetKitLogger logger,
  })  : _netKitManager = netKitManager,
        _logger = logger;

  final INetKitManager _netKitManager;
  final INetKitLogger _logger;

  [@override](/user/override)
  Future<void> deleteTodoById(int id) async {
    try {
      await _netKitManager.requestVoid(
        path: '/todos/$id',
        method: RequestMethod.delete,
      );
      _logger.debug('Todo deleted successfully');
    } on ApiException catch (e) {
      _logger.error(e.message);
    }
  }

  [@override](/user/override)
  Future<void> getTodo(int id) async {
    try {
      final todo = await _netKitManager.requestModel(
        path: '/todos/$id',
        method: RequestMethod.get,
        model: TodoModel(),
      );
      _logger.debug(todo.toString());
    } on ApiException catch (e) {
      _logger.error(e.message);
    }
  }

  [@override](/user/override)
  Future<void> getTodoList() async {
    try {
      final todos = await _netKitManager.requestList(
        path: '/todos',
        method: RequestMethod.get,
        model: TodoModel(),
      );
      _logger.info('Todos length: ${todos.length}');
    } on ApiException catch (e) {
      _logger.error(e.message);
    }
  }

  [@override](/user/override)
  Future<void> createTodo(TodoModel todo) async {
    try {
      final createdTodo = await _netKitManager.requestModel(
        path: '/todos',
        method: RequestMethod.post,
        model: TodoModel(),
        body: todo.toJson(),
      );
      _logger.debug('Created Todo: $createdTodo');
    } on ApiException catch (e) {
      _logger.error(e.message);
    }
  }
}

更多关于Flutter网络操作插件net_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络操作插件net_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用net_kit插件进行网络操作的代码示例。net_kit是一个假设的Flutter插件,用于简化网络请求。请注意,由于net_kit并非一个真实存在的官方插件,我将基于类似的网络请求插件(如diohttp)的功能来模拟一个示例。

首先,确保你的Flutter项目中已经添加了网络请求插件。由于net_kit不存在,这里我们使用dio作为替代,因为dio是一个流行的Flutter网络请求库。

  1. 添加依赖: 在你的pubspec.yaml文件中添加dio依赖:

    dependencies:
      flutter:
        sdk: flutter
      dio: ^4.0.0  # 请检查最新版本号
    

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

  2. 导入并使用dio进行网络请求

    创建一个新的Dart文件(例如network_service.dart),并在其中编写网络请求的逻辑:

    import 'package:dio/dio.dart';
    import 'dart:convert';
    
    class NetworkService {
      private static final String baseUrl = "https://api.example.com";
      private final Dio dio;
    
      NetworkService() {
        BaseOptions options = BaseOptions(
          baseUrl: baseUrl,
          connectTimeout: 5000,
          receiveTimeout: 30000,
        );
        dio = Dio(options);
      }
    
      // 发送GET请求
      Future<dynamic> getData(String endpoint) async {
        try {
          Response response = await dio.get(endpoint);
          return jsonDecode(response.data.toString());
        } catch (e) {
          print("Error in getData: $e");
          return null;
        }
      }
    
      // 发送POST请求
      Future<dynamic> postData(String endpoint, Map<String, dynamic> payload) async {
        try {
          Response response = await dio.post(
            endpoint,
            data: jsonEncode(payload),
            options: Options(
              contentType: Headers.formUrlEncodedContentType,
            ),
          );
          return jsonDecode(response.data.toString());
        } catch (e) {
          print("Error in postData: $e");
          return null;
        }
      }
    }
    
  3. 在主应用中调用网络服务

    在你的主应用文件(例如main.dart)中,使用NetworkService进行网络请求:

    import 'package:flutter/material.dart';
    import 'network_service.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Flutter Network Example'),
            ),
            body: NetworkExample(),
          ),
        );
      }
    }
    
    class NetworkExample extends StatefulWidget {
      @override
      _NetworkExampleState createState() => _NetworkExampleState();
    }
    
    class _NetworkExampleState extends State<NetworkExample> {
      String responseData = "";
    
      void fetchData() async {
        NetworkService networkService = NetworkService();
        dynamic response = await networkService.getData("/endpoint");
        setState(() {
          responseData = jsonEncode(response); // 假设返回的是JSON数据
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("Response Data:", style: TextStyle(fontSize: 18)),
              Text(responseData, style: TextStyle(fontSize: 16)),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: fetchData,
                child: Text("Fetch Data"),
              ),
            ],
          ),
        );
      }
    }
    

这个示例展示了如何使用dio插件在Flutter中进行GET和POST网络请求。如果你使用的net_kit插件有类似的API,你可以按照类似的方式实现网络请求。不过,由于net_kit并非真实存在的插件,你需要查阅其官方文档以获取正确的使用方法和API。

回到顶部