背景
我们知道dio
是一个非常强大的Dart
Http
请求库,支持非常多的功能,如果我们单单只是在外层包裹一层业务相关的封装,如果业务场景稍微复杂一点,这一层封装就显得臃肿和冗余了,当ios14.4.1更新了什么然我ios越狱们的网络层本身json解析也是初始化电脑时出现问题为业务层服务,业务层有了需求,网络层自然得有响应了,只是iOS响应的方式应该遵循低耦合、可用性、可维护性、可扩展性等原则。
设http代理计
我在做iOS原生开发的时候深受Casa大神网络层设计的影响,这初始化电脑里将服务层(service
)和接口层(api
)划分开,这样做的好处有:
- 在面对不同服务时可单独配置相关的
http
强求配置,通常我们的应用在开发的过程中都不会只和一个服务交互,所以在这种场景下是非常有必要的。 - 服务层和接口层职责拆分,让他们做自己该做的事情。

实现
服jsonobject务层
服务层的职责包括:baseUrl
的配appear置、服务公共请求头的配置、服务公共请求参数的配置、请求结果的加工、请求错误的统一处理等,除此之外还有token
验证、log
输出等。这里只提供一种封装思路具体的实现可json格式以根据业务场景自行实现。ios模拟器
首先我们会创建一个基类,这里命名为Service
,首先每一个服务都应该拥有一个Dio
实例:
import 'package:dio/dio.dart'; class Service { final Dio dio = Dio(); }
添加serviceKey
为了更好管理service
,这里引入一个service
来作为唯一标识。
import 'package:dio/dio.dart'; class Service { final Dio dio = Dio(); }
添加配置baJSONseUrl
这里httpwatch为了方json格式怎么打开便外部设置添加了set
和get
方法:
import 'package:dio/dio.dart'; class Service { final Dio dio = Dio(); late var _baseUrl = ""; set baseUrl(value) { if (_baseUrl == value) { return; } _baseUrl = value; dio.options.baseUrl = _baseUrl; } get baseUrl => _baseUrl; String serviceKey() { return ""; } }
添加公共请求头、公共参http://192.168.1.1登录数
import 'package:dio/dio.dart'; class Service { final Dio dio = Dio(); /*...省略其他设置...*/ Map<String, dynamic>? serviceHeader() { return null; } Map<String, dynamic>? serviceQuery() { return null; } Map<String, dynamic>? serviceBody() { return null; } }
添加公共结果处理、错误处理
在请求结果到达后可对Api
结果进行统一处理
import 'package:dio/dio.dart'; class Service { final Dio dio = Dio(); /*...省略其他设置...*/ Map<String, dynamic> responseFactory(Map<String, dynamic> dataMap) { /*...可对请求结果进行加工...*/ return dataMap; } String errorFactory(DioError error) { // 请求错误处理 String errorMessage = error.message; /*...具体的错误处理...*/ return errorMessage; } }
Service
的管理
这里是引入了ios是什么意思一个manager
来管理多个Service
,managjson数据er
为一个单例,用于注册和管理Service
,实现也很简单,就使用一个serviceMap
来存放Service
,在使用服务前调用方法registeredService()
注册需要服务即可,如果需要批量注册或者注销等功能自行添加即可appreciate。
import 'service.dart'; class ServiceManager { static final ServiceManager _instance = ServiceManager._internal(); factory ServiceManager() { return _instance; } ServiceManager._internal() { init(); } Map serviceMap = {}; void init() {} void registeredService(Service service) { service.initDio(); String key = service.serviceKey(); serviceMap[key] = service; } }
Api层
Api
层的职责包括设置path
、请求参数的组装、请求method
配置等功能了。
定义一个自定义的method
enum RequestMethod { get, post, put, delete, patch, copy }
serviceKey的配置
设置serviceKey
是为了http://192.168.1.1登录指定该Api
属于哪一个服务的:
class BaseApi { String serviceKey() { return ""; } }
加上path和method配置ios模拟器
class BaseApi { String serviceKey() { return ""; } String path() { return ""; } RequestMethod method() { return RequestMethod.get; } }
核心request方法
此处只实现了部分methodios是苹果还是安卓
,如有需求自行实现即可:
class BaseApi { /*...省略其他部分...*/ void request( {Map<String, dynamic>? query, Map<String, dynamic>? body, Map<String, dynamic>? header, required Function successCallBack, required Function errorCallBack}) async { //获取到对应的服务 Service service; if (ServiceManager().serviceMap.containsKey(serviceKey())) { service = ServiceManager().serviceMap[serviceKey()]; } else { throw Exception('服务尚未注册'); } Dio dio = service.dio; Response? response; Map<String, dynamic>? queryParams = {}; var globalQueryParams = service.serviceQuery(); if (globalQueryParams != null) { queryParams.addAll(globalQueryParams); } if (query != null) { queryParams.addAll(query); } Map<String, dynamic>? headerParams = {}; var globalHeaderParams = service.serviceHeader(); if (globalHeaderParams != null) { headerParams.addAll(globalHeaderParams); } if (header != null) { headerParams.addAll(header); } Map<String, dynamic>? bodyParams = {}; var globalBodyParams = service.serviceBody(); if (globalBodyParams != null) { bodyParams.addAll(globalBodyParams); } if (body != null) { bodyParams.addAll(body); } String url = path(); Options options = Options(headers: headerParams); try { switch (method()) { case RequestMethod.get: if (queryParams.isNotEmpty) { response = await dio.get(url, queryParameters: queryParams, options: options); } else { response = await dio.get(url, options: options); } break; case RequestMethod.post: if (body != null && body.isNotEmpty) { response = await dio.post(url, data: body, options: options); } else { response = await dio.post(url, options: options); } break; default: } } on DioError catch (error) { errorCallBack(service.errorFactory(error)); } if (response != null && response.data != null) { String dataStr = json.encode(response.data); Map<String, dynamic> dataMap = json.decode(dataStr); dataMap = service.responseFactory(dataMap); successCallBack(dataMap); } } }
使用
实现服务层
继承与Service
完成相应的父类方法重写以及ServiceKey
的定义:
const String customServiceKey = "CustomService"; class CustomService extends Service { @override String serviceKey() { return customServiceKey; } @override Map<String, dynamic>? serviceHeader() { Map<String, dynamic> header = <String, dynamic>{}; header["token"] = "..."; return header; } //初始化Dio @override void initDio() { dio.options.headers = { "Content-Type": 'application/json', }; dio.options.baseUrl = "http://abc/m/1234"; dio.options.connectTimeout = 15000; dio.options.receiveTimeout = 8000; dio.options.contentType = "application/json"; dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true)); } }
注册
在网络请求http://www.baidu.com前需要完成服务的注册:
void main() { runApp(MyApp()); //注册服务 ServiceManager().registeredService(CustomService()); }
Api的实现
Api
的实现也是继承于BaseApi
,然后实现iOS相关的父类方法重写即可:
class CustomApi extends BaseApi { @override String path() { return "/abc/api1"; } @override RequestMethod method() { return RequestMethod.post; } @override String serviceKey() { //返回服务中定义的key return customServiceKey; } }
Api的调用
对上面的Api
发起请求例子:
void requestApi() { CustomApi api = CustomApi(); Map<String, dynamic> body = {"key": value}; api.request( body: body, successCallBack: (data) { /* 请求结果处理 */ }, errorCallBack: (error) { /* 请求失败结果处理 */ } ); }
demo
评论(0)