yknetworking 0.1.6 copy "yknetworking: ^0.1.6" to clipboard
yknetworking: ^0.1.6 copied to clipboard

yknetworking.

yknetworking #

Flutter/Dart 网络请求库,基于 dio 5.x 和 connectivity_plus 构建。提供统一的 HTTP 请求、拦截器链、重试、取消、上传/下载、动态头/参以及网络连通性监听。

主页与仓库:https://github.com/yykedward/ykflutternetworking

许可证:MIT

特性 #

  • 直接返回 Future<T>,无需 switch/when 解包 —— 失败抛出 YKNetworkException
  • 拦截器链引擎:请求/响应/错误拦截器,优先级排序,类型安全跳过
  • 实例级拦截器注册,测试隔离
  • 内置拦截器:动态头、动态参数、数据洗练、重定向
  • 拦截器内重试 + 外部 retry() 两种重试路径
  • CancelToken 支持,返回 YKCancelled<T>(safe API)
  • 安全 API(safeRequest()/safeUpload()/safeDownload()/safeRetry())返回 YKResult<T> 密封类型供需要完全控制的场景
  • 上传(multipart/form-data)、下载(支持保存到本地)
  • 全局超时、基础地址、公共参数、公共头配置
  • 网络连通性监听 YKNetworkConnectivity(基于 connectivity_plus

环境与依赖 #

  • Dart >=3.0.0 <4.0.0
  • Flutter
  • dio: ^5.5.0
  • connectivity_plus: ^6.0.5

安装 #

flutter pub add yknetworking

或在 pubspec.yaml 中添加:

dependencies:
  yknetworking: ^0.1.6

快速开始 #

全局配置 #

import 'package:yknetworking/yk_networking.dart';

void setupNetworking() {
  final config = YKNetworkingConfig.getInstance();
  config.baseUrl = 'https://api.example.com';
  config.timeOut = 30;
  config.receiveTimeout = 30;
  config.commHeader = {'Accept': 'application/json'};
  config.commParams = {'locale': 'zh-CN'};
}

Primary API — 直接 await(推荐) #

final api = YKNetworking(
  commonHeader: {'Authorization': 'Bearer token'},
);

try {
  // 直接获取数据,无需 switch/when
  final users = await api.get<Map>('/users', params: {'page': '1'});

  final result = await api.post<Map>(
    '/login',
    params: {'user': 'admin', 'pwd': 'secret'},
    contentType: YKNetworkingContentType.applicationJson,
  );

  final profile = await api.get<User>('/profile');
  print(profile.name);
} on YKNetworkException catch (e) {
  print('Request failed: ${e.type} - ${e.message}');
}

Safe API — 需要 retry 或完全控制时 #

final result = await api.safeRequest<User>('/profile', method: YKNetworkingMethod.get);
switch (result) {
  case YKSuccess(:final data, :final statusCode):
    print('OK $statusCode: $data');
  case YKFailure(:final exception, :final retryContext, :final retryCount):
    if (retryContext != null) {
      await api.safeRetry<User>(retryContext,
        headers: {'Authorization': 'Bearer refreshed'},
      );
    }
  case YKCancelled():
    print('Request cancelled');
}

拦截器 #

自定义拦截器 #

class LogInterceptor extends YKInterceptor {
  @override int get priority => 100;
  @override String get name => 'logger';
  @override YKInterceptorType get type => YKInterceptorType.all;

  @override Future<void> onRequest(YKNetworkingRequest request) async {
    print('→ ${request.method.value()} ${request.path}');
  }

  @override Future<void> onResponse(YKInterceptorResponse response) async {
    print('← ${response.statusCode}');
  }
}

final api = YKNetworking()
  ..addInterceptor(LogInterceptor())
  ..addInterceptor(HandleDataInterceptor(
    handler: (req, resp) {
      final d = resp.data;
      if (d is Map && d['code'] != 0) {
        return Exception(d['message'] ?? 'business error');
      }
      return null;
    },
  ));

拦截器优先级范围 #

范围 用途
0-99 库内置:请求预处理(DynamicHeader、DynamicParams)
100-199 用户:请求拦截器
200-299 用户:响应拦截器
300-399 库内置:数据洗练(HandleData)
400-499 用户:错误拦截器
500-599 库内置:重定向

跳过拦截器 #

// 按名称跳过
api.get<Map>('/users',
  skipInterceptors: [const ByName(BuiltInInterceptors.handleData)],
);

// 按类型跳过
api.post<Map>('/login',
  skipInterceptors: [const ByType<LogInterceptor>()],
);

拦截器内重试 #

class TokenRefreshInterceptor extends YKInterceptor {
  @override int get priority => 400;
  @override String get name => 'tokenRefresh';
  @override YKInterceptorType get type => YKInterceptorType.error;

  @override Future<void> onError(
    YKNetworkingRequest request,
    YKNetworkException error,
    YKRetryHandler retry,
  ) async {
    if (error.statusCode == 401) {
      final newToken = await refreshToken();
      request.commheader!['Authorization'] = 'Bearer $newToken';
      await retry(); // 重新执行完整链,自动跳过自身
    }
  }
}

外部 retry #

final result = await api.safeRequest<User>('/profile', method: YKNetworkingMethod.get);
if (result case YKFailure(:final retryContext) when retryContext != null) {
  final newToken = await refreshToken();
  // throwing API:直接返回 T
  final user = await api.retry<User>(retryContext,
    headers: {'Authorization': 'Bearer $newToken'},
  );
}

请求取消 #

final cancelToken = CancelToken();
final future = api.safeRequest<Map>('/slow', method: YKNetworkingMethod.get, cancelToken: cancelToken);
cancelToken.cancel('no longer needed');
// 返回 YKCancelled<Map>,或 throwing API 抛出 YKNetworkException(type: cancelled)

上传与下载 #

// 上传
final data = await api.upload<Map>(
  '/files', 'local.png', 'local.png', 'image/png', 'file',
  params: {'dir': 'images'},
  progressCallBack: (sent, total) => print('${sent}/${total}'),
);

// 下载到本地
final bytes = await api.download<Uint8List>(
  'https://host/file.bin',
  downloadPath: '/tmp/file.bin',
  progressCallBack: (received, total) => print('${received}/${total}'),
);

网络连通性 #

final connectivity = YKNetworkConnectivity.getInstance();
await connectivity.setup();
final isOnline = await connectivity.check();

在 Flutter 中可结合 ChangeNotifier 订阅 didConnect 状态变化。

生命周期 #

final api = YKNetworking()
  ..addInterceptor(myInterceptor);

// 完成后释放资源(取消进行中请求,dispose 所有拦截器)
api.dispose();

开发 #

flutter test          # 运行测试
flutter analyze       # 静态分析

API 结构 #

文件 职责
lib/yk_networking.dart 公共 API:YKNetworking 类(throwing API + safeRequest()/safeUpload()/safeDownload()/safeRetry() 安全入口)
lib/yk_base_networking.dart 静态执行层:拦截器链引擎 + Dio 通信
lib/yk_networking_config.dart 单例:全局 Dio 配置
lib/yk_networking_request.dart 请求模型 + YKNetworkingMethod / YKNetworkingContentType
lib/yk_result.dart YKResult<T> 密封类 + RetryContext
lib/yk_interceptor.dart 拦截器抽象类 + InterceptorRef + 内置拦截器
lib/yk_interceptor_response.dart 响应包装类型
lib/yk_network_exception.dart YKNetworkException + YKErrorType
lib/yk_network_connectivity.dart 网络连通性监听

变更日志 #

CHANGELOG.md

1
likes
115
points
238
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

yknetworking.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

connectivity_plus, dio, flutter

More

Packages that depend on yknetworking