如何用 Flutter 解析动态 JSON?

Posted

技术标签:

【中文标题】如何用 Flutter 解析动态 JSON?【英文标题】:How to parse dynamic JSON with Flutter? 【发布时间】:2021-12-18 05:03:33 【问题描述】:

我不明白如何解析从 firebase 获得的 JSON 文件。

这是 JSON 文件的格式


  "water" : 
    "-MnRJkFC3--ZOTmpF1xN" : 
      "milliliters" : 0.14,
      "time" : "16:26:25"
    ,
    "-MnRJkZRwZYEInHfSKIY" : 
      "milliliters" : 48.83,
      "time" : "16:26:25"
    ,
    "-MnRJksES18hY765rxxq" : 
      "milliliters" : 41.44,
      "time" : "16:26:25"
    ,
    "-MnRJlDn6o4RmiGRJS-E" : 
      "milliliters" : 11.37,
      "time" : "16:26:25"
    
  

这就是我读取 JSON 文件的方式

Future loadSalesData() async 
  final String jsonString = await getJsonFromFirebase();
  final dynamic jsonResponse = json.decode(jsonString);
  for (Map<String, dynamic> i in jsonResponse)
    chartData.add(SalesData.fromJson(i));
  

getJsonFromFirebase() 看起来像这样:

Future<String> getJsonFromFirebase() async 
  String url =
      "https://emailpassword. . .seio.com/water.json";
  http.Response response = await http.get(Uri.parse(url));
  return response.body;

当您单击链接时,它会将您发送到如下所示的 JSON 文件


    "-Mnbk2ye2P8bfpaQvNaU": 
        "milliliters": 0.0,
        "time": "18:07:00"
    ,
    "-Mnbk6wd-wJze8P0JknK": 
        "milliliters": 0.12,
        "time": "18:07:00"
    ,
    "-Mnbk7Ek629vgBu-MiLg": 
        "milliliters": 44.91,
        "time": "18:07:00"
    ,
    "-Mnbk7bPuzqwsz9d5nm6": 
        "milliliters": 5.43,
        "time": "18:07:00"
    ,
    "-Mnbk7v7MADi7YzEbeFI": 
        "milliliters": 24.54,
        "time": "18:07:00"
    ,
    "-Mnbk8DGfqswckdsA1qP": 
        "milliliters": 47.58,
        "time": "18:07:00"
    ,
    "-Mnbk8Xw2kJPxLrqCl6h": 
        "milliliters": 13.98,
        "time": "18:07:00"
    

我得到错误

_InternalLinkedHashMap' 不是“Iterable”类型的子类型

【问题讨论】:

getJsonFromFirebase 长什么样子? 嗨弗兰克,这就是 getJsonFromFirebase 的样子 Fu​​ture getJsonFromFirebase() async String url = "emailpass. . . .firebaseio.com/water.json"; http.Response 响应 = 等待 http.get(Uri.parse(url));返回响应.body; 该链接将您发送到我的实时数据库中的 JSON 文件 当您点击链接时,JSON 文件看起来像这样 "-Mnbk2ye2P8bfpaQvNaU":"milliliters":0.0,"time":"18:07:00","-Mnbk6wd-wJze8P0JknK ":"毫升":0.12,"时间":"18:07:00","-Mnbk7Ek629vgBu-MiLg":"毫升":44.91,"时间":"18:07:00"," -Mnbk7bPuzqwsz9d5nm6":"毫升":5.43,"时间":"18:07:00","-Mnbk7v7MADi7YzEbeFI":"毫升":24.54,"时间":"18:07:00"," -Mnbk8DGfqswckdsA1qP":"毫升":47.58,"时间":"18:07:00","-Mnbk8Xw2kJPxLrqCl6h":"毫升":13.98,"时间":"18:07:00" 【参考方案1】:

根据您收到的 JSON 格式,json.decode 将返回一个Map&lt;String, dynamic&gt;(更具体地说是_InternalLinkedHashMap&lt;String, dynamic&gt; 专业化的一个实例)。此类型未实现 Iterable,因此您无法使用 for-in 构造直接对其进行迭代,而这正是您在运行时遇到的确切错误。

根据构建SalesData 实例所需的内容,您有两种选择:

迭代entries 属性,如果您需要每个项目的key"-Mnbk2ye2P8bfpaQvNaU""-Mnbk6wd-wJze8P0JknK" 等),否则 如果不这样做,请遍历 values 属性

参赛作品

迭代:
for (MapEntry<String, dynamic> i in jsonResponse.entries) 
  chartData.add(SalesData.fromJson(i));

SalesData.fromJson:
SalesData.fromJson(MapEntry<String, dynamic> data) 
  id = data.key;
  milliliters = data.value['milliliters'];
  time = data.value['time'];

价值观

迭代:
for (Map<String, dynamic> i in jsonResponse.values) 
  chartData.add(SalesData.fromJson(i));

SalesData.fromJson:
SalesData.fromJson(Map<String, dynamic> data) 
  milliliters = data['milliliters'];
  time = data['time'];

类型推断

此外,无论您决定如何迭代 Map 实例,您都可以利用 Dart 的 type inference 稍微清理代码,因此(假设您正在迭代条目)loadSalesData 可能变为:

Future loadSalesData() async 
  final jsonString = await getJsonFromFirebase();
  final jsonResponse = json.decode(jsonString);

  for (final i in jsonResponse.entries) 
    chartData.add(SalesData.fromJson(i));
  

getJsonFromFirebase 可能变成:

Future<String> getJsonFromFirebase() async 
  final url = "http://localhost:8080/data.json";
  final response = await http.get(Uri.parse(url));
  return response.body;

【讨论】:

非常感谢,写的很详细,帮助很大【参考方案2】:

似乎flutter 不理解jsonResponseiterable,因为您将其定义为dynamic

调整定义告诉flutter它是一张地图:

final Map<String, dynamic> jsonResponse = json.decode(jsonString);

【讨论】:

非常感谢,这对我有帮助 这完全是错误的。它所做的只是将错误从运行时错误(如上)更改为编译时错误,因为现在编译器知道类型不是Iterable。你真的试过@Nairobi 或@Canada2000 吗? 是的,我确实尝试过,我只需要更改 For 循环,它就能够从 firebase 获取 JSON 文件 @msbit 我还按照您的指示更改了我的代码,并且效果很好。

以上是关于如何用 Flutter 解析动态 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

我如何用 alamofire 解析 JSON

如何用Python解析多层嵌套的JSON?

c#生成的Json如何用python解析

如何用 ijson 和 python 解析 json

如何用play json库解析二级JSON数组?

我如何用alamofire解析JSON