Flutter清理API接口插件clean_api的使用

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

Flutter清理API接口插件clean_api的使用

1. 简介

clean_api 是一个用于简化Flutter应用程序中API调用的插件。它可以帮助开发者更方便地处理API请求,并且提供了错误处理、日志记录等功能。本文将详细介绍如何使用 clean_api 插件来清理和简化API接口调用。

2. 使用步骤

2.1 设置基础URL

在使用 clean_api 之前,首先需要设置API的基础URL。你可以在 main.dart 文件中进行设置:

void main() {
  // 设置API的基础URL,并开启日志记录
  CleanApi.instance.setup(baseUrl: 'https://catfact.ninja/', showLogs: true);

  runApp(const MyApp());
}
  • baseUrl: API的基础URL。
  • showLogs: 是否显示API请求的日志,默认为 false。开启后,所有的API请求和响应都会打印到控制台,方便调试。
2.2 获取数据

接下来,我们可以使用 clean_api 来获取API数据。以下是一个完整的示例,展示了如何从API获取猫的事实(Cat Fact)并显示在界面上。

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

void main() {
  // 设置API的基础URL,并开启日志记录
  CleanApi.instance.setup(baseUrl: 'https://catfact.ninja/', showLogs: true);

  runApp(const MyApp());
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Clean Api Example',
      home: MyHomePage(title: 'Clean Api Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String text = 'Press the button to load fact';  // 初始文本
  final cleanApi = CleanApi.instance;  // 获取CleanApi实例

  // 获取猫的事实
  void getCatFacts() async {
    setState(() {
      text = 'Loading';  // 更新状态为加载中
    });

    // 发起GET请求,获取猫的事实
    final Either<CleanFailure, CatModel> response = await cleanApi.get<CatModel>(
      fromData: (json) {
        return CatModel.fromJson(json);  // 将JSON转换为CatModel对象
      },
      endPoint: 'fact',  // API的端点
    );

    // 处理响应结果
    response.fold(
      (l) {  // 如果是失败
        CleanFailureDialogue.show(context, failure: l);  // 显示错误对话框
      },
      (r) {  // 如果是成功
        setState(() {
          text = r.fact;  // 更新状态为获取到的事实
        });
      },
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: Text(
            text,  // 显示当前的状态或事实
            style: Theme.of(context)
                .textTheme
                .titleLarge
                ?.copyWith(color: Colors.green),  // 设置文本样式
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: getCatFacts,  // 点击按钮时调用getCatFacts方法
        tooltip: 'Fetch api',  // 按钮提示
        child: const Icon(Icons.next_plan),  // 按钮图标
      ),
    );
  }
}

// 定义猫的事实模型
class CatModel {
  final String fact;  // 猫的事实内容
  final int length;  // 事实的长度

  CatModel({
    required this.fact,
    required this.length,
  });

  // 复制构造函数
  CatModel copyWith({
    String? fact,
    int? length,
  }) {
    return CatModel(
      fact: fact ?? this.fact,
      length: length ?? this.length,
    );
  }

  // 将对象转换为JSON格式
  Map<String, dynamic> toJson() {
    return {
      'fact': fact,
      'length': length,
    };
  }

  // 从JSON格式转换为对象
  factory CatModel.fromJson(Map<String, dynamic> map) {
    return CatModel(
      fact: map['fact'] ?? '',  // 如果没有fact字段,则返回空字符串
      length: map['length']?.toInt() ?? 0,  // 如果没有length字段,则返回0
    );
  }

  [@override](/user/override)
  String toString() => 'CatModel(fact: $fact, length: $length)';  // 重写toString方法

  [@override](/user/override)
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is CatModel && other.fact == fact && other.length == length;
  }

  [@override](/user/override)
  int get hashCode => fact.hashCode ^ length.hashCode;
}

更多关于Flutter清理API接口插件clean_api的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter清理API接口插件clean_api的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用clean_api插件来清理API接口的一个示例。clean_api插件可以帮助你管理和清理API调用,但请注意,这个插件可能是一个假设的或自定义的插件,因为在实际Flutter生态系统中,没有一个广泛认知的名为clean_api的官方插件。不过,我们可以模拟一个类似的机制来展示如何管理和清理API调用。

假设我们有一个自定义的CleanApi类来管理API调用,并且我们希望通过某种方式“清理”或取消未完成的请求。以下是一个简化的示例:

1. 创建一个CleanApi

首先,我们创建一个CleanApi类,用于管理API请求和取消它们。

import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

class CleanApi {
  final Map<String, CancelableOperation> _operations = {};

  Future<Map<String, dynamic>> get(String url, {String requestId}) async {
    if (requestId != null && _operations.containsKey(requestId)) {
      // Cancel the previous operation if it exists
      _operations[requestId]?.cancel();
      _operations.remove(requestId);
    }

    final completer = Completer<Map<String, dynamic>>();
    CancelableOperation operation;

    operation = CancelableOperation.fromFuture(
      http.get(Uri.parse(url)).then((response) {
        if (response.statusCode == 200) {
          final jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
          completer.complete(jsonResponse);
        } else {
          throw Exception('Failed to load data: ${response.statusCode}');
        }
      }).catchError((error) {
        completer.completeError(error);
      }),
    );

    if (requestId != null) {
      _operations[requestId] = operation;
    }

    return completer.future;
  }

  void cancelOperation(String requestId) {
    _operations[requestId]?.cancel();
    _operations.remove(requestId);
  }
}

2. 使用CleanApi

接下来,我们在Flutter应用中使用这个CleanApi类来管理API请求。

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

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

class MyApp extends StatelessWidget {
  final CleanApi _api = CleanApi();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Clean API Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  try {
                    final response = await _api.get(
                      'https://jsonplaceholder.typicode.com/posts/1',
                      requestId: 'fetchPost1',
                    );
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Data fetched: ${response['title']}')),
                    );
                  } catch (error) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Error: $error')),
                    );
                  }
                },
                child: Text('Fetch Post 1'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  _api.cancelOperation('fetchPost1');
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('Request canceled')),
                  );
                },
                child: Text('Cancel Request'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

3. CancelableOperation

为了支持取消操作,我们需要一个CancelableOperation类。这可以通过包装Future并添加一个取消回调来实现。以下是一个简单的实现:

import 'dart:async';

class CancelableOperation {
  final Future<void> _future;
  final Completer<void> _completer = Completer<void>();
  bool _isCanceled = false;

  CancelableOperation._(this._future);

  factory CancelableOperation.fromFuture(Future<void> future) {
    final cancelable = CancelableOperation._(future);
    future.then((_) => cancelable._completer.complete(), onError: cancelable._completer.completeError);
    return cancelable;
  }

  void cancel() {
    if (!_isCanceled) {
      _isCanceled = true;
      _completer.completeError(OperationCanceledError());
    }
  }

  Future<T> get future<T> {
    final completer = Completer<T>();
    _future.then(
      (_) => completer.complete(null as T),
      onError: (error) {
        if (error is OperationCanceledError || _isCanceled) {
          completer.completeError(OperationCanceledError());
        } else {
          completer.completeError(error);
        }
      },
    );
    return completer.future;
  }
}

class OperationCanceledError implements Exception {}

总结

这个示例展示了如何创建一个自定义的CleanApi类来管理API请求,并通过CancelableOperation类支持取消操作。虽然这不是一个实际的clean_api插件,但它模拟了如何管理和清理API调用的机制。你可以根据自己的需求进一步扩展和优化这个示例。

回到顶部