• Flutter如何使用extension method实现map的扩展函数
  • 发布于 2个月前
  • 294 热度
    0 评论
相信做Flutter开发的小伙伴们曾经都有这样的痛苦,接口明明是联调OK的,怎么提测以后接口就出问题了,有一种情况是这样的,后台哥们很不负责任的调整了字段类型,或者修改了字段名,再或者缺少了原有返回的字段。

首先看下,相信大家正常都是这样解析json的
//假如已经获取到了从后台的response
Map<String, dynamic> json =  [];

//解析String值与int值
String nickname = json["nickname"];
int userId = json["userId"];
这种写法,如果后台没有返回nickname字段,或者userId后台返回的是字符串类型,这里json解析就会报错,flutter不像原生解析一样有json.optString或者json.optInt这样的方法,当然在flutter中map也有containsKey方法,判断该字段是否存在,难道.....我要对每个字段进行判断吗?如果非要我这样做,我会把后台杀了。

有没有什么方法可以像原生Android一样解析,直接json.optString()一样处理,及时后台没有返回该字段,或者数据类型对不上,app这边依然可以正常运行,不会程序报错,答案是有的,那就是extension method处理,实现map的扩展函数(getString,getInt,getBool)这样的方法,然后在里面自己进行容错处理即可)java是不能实现扩展函数的,kotlin与flutter却可以,废话不多说,直接上代码吧。
/**
 * 堆代码 duidaima.com
 * 扩展工具类
 */
extension ExtensionUtils on Map {

  /**
   * 返回一个int值
   */
  int getInt(String key, {int defValue = 0}) {
    try {
      if (containsKey(key)) {
        var value = this[key];
        if (null == value) {
          return defValue;
        } else if (value is String) {
          return int.parse(value);
        }
        return value;
      }
    } on Exception {
    } catch (e) {}
    return defValue;
  }

  /**
   * 返回一个String值
   */
  String getString(String key, {String defValue = ""}) {
    try {
      if (containsKey(key)) {
        var value = this[key];
        if (null == value) {
          return defValue;
        } else if (value is int) {
          return value.toString();
        }
        return this[key];
      }
    } on Exception {
    } catch (e) {}
    return defValue;
  }

  /**
   * 返回一个map
   */
  Map<String, dynamic> getMap(String key) {
    try {
      if (containsKey(key)) {
        return this[key];
      }
    } on Exception {
    } catch (e) {}
    return {};
  }

  /**
   * 返回一个对象
   */
  T getObject<T>(String key, T Function(Map<String, dynamic>) parseModel) {
    try {
      if (this.containsKey(key) && null != this[key]) {
        return parseModel(this[key]);
      } else {
        return parseModel({});
      }
    } on Exception {
      return parseModel({});
    }
  }

  /**
   * 解析list
   */
  List<T> getList<T>(String key, T Function(dynamic data) parseModel) {
    try {
      List list = this[key] ?? [];
      List<T> datas = list.map((e) => parseModel(e)).toList();
      return datas;
    } on Exception {
      return [];
    }
  }
}
最后看下我是如何调用的。
解析int,String
import 'package:app_flutter/utils/extensions_utils.dart';
class Shift {
  String? endTime;
  int? groupId;
  String? workStatus; //WORKING:值班中, RESTING:休息中,HANDOVER_WORK: 交班, RECEIVING_WORK: 接班
  String? workStatusDesc;

  Shift.fromJson(Map<String, dynamic> json) {
    endTime = json.getString("endTime");
    groupId = json.getInt("groupId");
    workStatus = json.getString("workStatus");
    workStatusDesc = json.getString("workStatusDesc");
  }
}
解析object对象与解析list数组
import 'package:app_flutter/utils/extensions_utils.dart';

import 'message_ext.dart';

/**
 * 未读消息体
 */
class MessageNotify {

  late String content;//    内容  string
  late MessageExt ext;//    扩展数据    object
  late String id;// id  string
  late int isRead;//    是否已读(0:否,1:是)   integer
  late String msgId;//  消息id    integer
  late String recId;//  接收者id   string
  late List<String> tags;// 标签数组    array   string
  late String time;//   时间  string
  late String title;//  标题

  MessageNotify.from(Map<String, dynamic> map){
    content = map.getString("content");
    ext = map.getObject("ext", (data){ return MessageExt.from(data);});
    id = map.getString("id");
    isRead = map.getInt("isRead");
    msgId = map.getString("msgId");
    recId = map.getString("recId");
    tags = map.getList("tags", (item){return item.toString();});
    time = map.getString("time");
    title = map.getString("title");
  }
}
补充下MessageExt.dart类
import 'package:app_flutter/constant/asset_path_constant.dart';
import 'package:app_flutter/utils/extensions_utils.dart';

/**
 * 未读消息-扩展字段
 */
class MessageExt {
  late int msgType; //: 0事件,1待办,2逾期,3临期
  late String typeId; //: 事件ID或工单ID
  late String businessId;// 业务ID,当type为 3,4的时候,该字段有值
  late int type; //: 0告警事件,1报修事件,2告警工单,3保养工单,4巡检工单,5维修工单
  late String msgTip; //:严重,巡检,维保,告警处置
  late String msgIcon; //: 图标路径

  MessageExt.from(Map<String, dynamic> map) {
    msgType = map.getInt("msgType");
    typeId = map.getString("typeId");
    type = map.getInt("type");
    msgTip = map.getString("msgTip");
    msgIcon = map.getString("msgIcon");
    businessId = map.getString("businessId");
  }
}
此工具类一出,方便了组内的其他小伙伴,老大直接给我call了波666,当时搞的我都飘了。
用户评论