Flutter网络交互插件packagist_network的使用

Flutter网络交互插件packagist_network的使用

网络

示例

使用

要使用此插件,在您的 pubspec.yaml 文件中添加 network 作为依赖项。

dependencies:
  network: 
    git:
      url: https://github.com/flutter-packagist/network.git

支持的方法

  • ✅ GET
  • ✅ POST
  • ✅ PUT
  • ✅ DELETE
  • ✅ PATCH
  • ✅ HEAD
  • ✅ DOWNLOAD

示例

初始化

HttpRequest().init(HttpRequestSetting(
  baseUrl: EnvConfig.host,
  interceptors: [
    RetryOnConnectionChangeInterceptor(),
    DioLogInterceptor(),
    CancelTokenInterceptor(),
  ],
));

GET

await HttpRequest().get(
  'get',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

POST

await HttpRequest().post(
  'post',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

PUT

await HttpRequest().put(
  'put',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

DELETE

await HttpRequest().delete(
  'delete',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

PATCH

await HttpRequest().patch(
  'patch',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

HEAD

await HttpRequest().head(
  'head',
  onSuccess: (data) {
    showToast("请求成功: ${data.toString()}");
  },
  onFailed: (code, DioException? error) {
    logE('code: $code, msg: $error');
  },
);

下载

await HttpRequest().download(
  url,
  '${(await getTemporaryDirectory()).path}/test.jpg',
  onReceiveProgress: (count, total) {
    logD('进度:$count / $total');
  },
  onSuccess: (data) {
    showToast("下载完成");
  },
  onFailed: (code, error) {
    logE('code: $code, msg: $error');
  },
);

在 Web 上,您可以使用 download(url) 来下载文件。例如:

/// 下载链接内容
static void download(String url) {
  html.AnchorElement anchorElement = html.AnchorElement(href: url);
  anchorElement.download = url;
  anchorElement.click();
}

上传

选择文件

MultipartFile? multipartFile;
if (GetPlatform.isWeb) {
  FilePickerResult? result = await FilePicker.platform.pickFiles();
  Uint8List? fileBytes = result!.files.first.bytes;
  String fileName = result.files.first.name;
  if (fileBytes == null) {
    showToast("文件为空");
    return;
  }
  multipartFile = MultipartFile.fromBytes(
    fileBytes,
    filename: fileName,
  );
} else {
  FilePickerResult? result = await FilePicker.platform.pickFiles();
  if (result?.files.single.path == null) {
    showToast("文件为空");
    return;
  }
  showToast("文件路径: ${result!.files.single.path}");
  multipartFile = await MultipartFile.fromFile(result.files.single.path!);
}

上传文件

await HttpRequest().post(
  'upload',
  formData: {'file': multipartFile},
  onSuccess: (data) {},
  onFailed: (code, msg) {},
  onSendProgress: (count, total) {
    logD('进度:$count / $total');
  },
);

拦截器

  • RetryOnConnectionChangeInterceptor: 当网络连接更改时重试。
  • DioLogInterceptor: 日志拦截器。
  • CancelTokenInterceptor: 在发送请求时会自动创建一个取消令牌,并将其添加到 CancelTokenPool。请求完成后或被取消后,将从 CancelTokenPool 中移除取消令牌。

自定义拦截器

class CustomInterceptor extends Interceptor {
  [@override](/user/override)
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    super.onRequest(options, handler);
    
  }

  [@override](/user/override)
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    super.onResponse(response, handler);
    
  }

  [@override](/user/override)
  void onError(DioException err, ErrorInterceptorHandler handler) {
    super.onError(err, handler);
    
  }
}

添加拦截器

HttpRequest().init(HttpRequestSetting(
  baseUrl: EnvConfig.host,
  interceptors: [
    ...
    CustomInterceptor(),
  ],
));

取消请求

取消令牌

final cancelToken = CancelToken();
await HttpRequest().get(
  'get',
  cancelToken: cancelToken,
);

cancelToken.cancel();

绑定控制器

如果您希望在控制器被释放时取消网络请求,可以使用 CancelTokenPool().cancel(this) 来取消它。并将请求绑定到控制器。

class NetworkController extends BaseController<NetworkModel> {
  [@override](/user/override)
  NetworkModel model = NetworkModel();
  
  [@override](/user/override)
  onReady() {
    super.onReady();
    get();
  }

  [@override](/user/override)
  void onClose() {
    // 取消当前控制器绑定的网络请求
    CancelTokenPool().cancel(this);
    super.onClose();
  }
  
  void get() {
    HttpRequest().get(
      'get',
      bind: this,
    );
  }
}

记得在初始化 HttpRequest 时添加 CancelTokenInterceptor()

HttpRequest().init(HttpRequestSetting(
  baseUrl: EnvConfig.host,
  interceptors: [
    ...
    CancelTokenInterceptor(),
  ],
));

安全转换

  • toInt(value, {int defaultValue = 0})
  • toDouble(value, {double defaultValue = 0.0})
  • toBool(value, {bool defaultValue = false})
  • toString(value, {String defaultValue = ""})
  • toMap(value, {Map<String, dynamic>? defaultValue})
  • toList(value, {List? defaultValue})
  • asInt(Map<String, dynamic>? json, String key, {int defaultValue = 0})
  • asDouble(Map<String, dynamic>? json, String key, {double defaultValue = 0.0})
  • asBool(Map<String, dynamic>? json, String key, {bool defaultValue = false})
  • asString(Map<String, dynamic>? json, String key, {String defaultValue = ""})
  • asMap(Map<String, dynamic>? json, String key, {Map<String, dynamic>? defaultValue})
  • asList(Map<String, dynamic>? json, String key, {List? defaultValue})

示例

test("convert dynamic to safe type", () {
  Object? a;
  print(a.runtimeType); // print: Null
  print(toInt(a).runtimeType); // print: int
  print(toInt(a)); // print: 0
});

test("convert from json key to safe type", () {
  final json = {
    'int': 1,
    'double': 1.0,
    'bool': true,
    'string': 'string',
    'map': {'key': 'value'},
    'list': ["1", "2", "3"],
  };

  print(asInt(json, 'int')); // print: 1
  print(asDouble(json, 'double')); // print: 1.0
  print(asBool(json, 'bool')); // print: true
  print(asString(json, 'string')); // print: string
  print(asMap(json, 'map')); // print: {key: value}
  print(asList(json, 'list').map((e) => toString(e)).toList()); // print [1, 2, 3]

  print("\n");
  print(asMap(json, 'int')); // print: {}
  print(asMap(json, 'double')); // print: {}
  print(asMap(json, 'bool')); // print: {}
  print(asMap(json, 'string')); // print: {}
  print(asMap(json, 'map')); // print: {}
  print(asMap(json, 'list')); // print: {}

  print("\n");
  print(asList(json, 'map').map((e) => toString(e)).toList()); // print []
});

完整示例Demo

示例代码

example/lib/main.dart

import 'dart:async';

import 'package:example/network/network_page.dart';
import 'package:flutter/material.dart';
import 'package:log_wrapper/log/log.dart';
import 'package:oktoast/oktoast.dart';

import 'app_service.dart';

void main() {
  runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await AppService.init();
    runApp(const MyApp());
  }, (Object error, StackTrace stack) {
    logStackE("$error", error, stack);
  });
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const NetworkPage(),
      builder: (context, widget) {
        return OKToast(child: widget!);
      },
    );
  }
}

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

1 回复

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


package_network 并不是一个广为人知的 Flutter 插件,可能是一个自定义的或特定项目的网络交互插件。如果你在寻找一个用于 Flutter 网络交互的常用插件,通常推荐使用 httpdio 插件,它们都是非常流行的网络请求库。

不过,如果你确实在使用一个名为 package_network 的插件,以下是一些常见的使用步骤和示例代码,假设它的功能类似于 httpdio

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 package_network 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  package_network: ^1.0.0  # 请根据实际情况填写版本号

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

2. 导入插件

在你的 Dart 文件中导入 package_network 插件。

import 'package:package_network/package_network.dart';

3. 初始化网络客户端

假设 package_network 提供了一个网络客户端类 NetworkClient,你可以初始化它。

final networkClient = NetworkClient();

4. 发送 GET 请求

使用 networkClient 发送一个 GET 请求。

void fetchData() async {
  try {
    final response = await networkClient.get('https://jsonplaceholder.typicode.com/posts');
    if (response.statusCode == 200) {
      // 解析响应数据
      var data = response.data;
      print(data);
    } else {
      print('Request failed with status: ${response.statusCode}');
    }
  } catch (e) {
    print('Error: $e');
  }
}

5. 发送 POST 请求

发送一个 POST 请求。

void postData() async {
  try {
    final response = await networkClient.post(
      'https://jsonplaceholder.typicode.com/posts',
      body: {
        'title': 'foo',
        'body': 'bar',
        'userId': 1,
      },
    );
    if (response.statusCode == 201) {
      // 解析响应数据
      var data = response.data;
      print(data);
    } else {
      print('Request failed with status: ${response.statusCode}');
    }
  } catch (e) {
    print('Error: $e');
  }
}

6. 处理错误和异常

在网络请求中,处理错误和异常是非常重要的。你可以使用 try-catch 块来捕获异常并进行处理。

7. 其他功能

如果 package_network 提供了其他功能,比如文件上传、下载、拦截器等,你可以根据具体的 API 文档进行使用。

8. 示例项目

假设你有一个完整的示例项目,你可以在 main.dart 中调用这些方法。

import 'package:flutter/material.dart';
import 'package:package_network/package_network.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Package Network Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: fetchData,
                child: Text('Fetch Data'),
              ),
              ElevatedButton(
                onPressed: postData,
                child: Text('Post Data'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

final networkClient = NetworkClient();

void fetchData() async {
  try {
    final response = await networkClient.get('https://jsonplaceholder.typicode.com/posts');
    if (response.statusCode == 200) {
      var data = response.data;
      print(data);
    } else {
      print('Request failed with status: ${response.statusCode}');
    }
  } catch (e) {
    print('Error: $e');
  }
}

void postData() async {
  try {
    final response = await networkClient.post(
      'https://jsonplaceholder.typicode.com/posts',
      body: {
        'title': 'foo',
        'body': 'bar',
        'userId': 1,
      },
    );
    if (response.statusCode == 201) {
      var data = response.data;
      print(data);
    } else {
      print('Request failed with status: ${response.statusCode}');
    }
  } catch (e) {
    print('Error: $e');
  }
}
回到顶部