如何在Flutter中正确解析此JSON API?

时间:2019-06-30 23:28:56

标签: json flutter

我开始学习使用Flutter SDK编写iOS应用程序。我目前正在开发一款可跟踪视频游戏中称为“入侵”的事件的应用。

以下是该API的示例:

{
   lastUpdated: 1561927328,
   invasions: {
      Whoosh Rapids: {
        asOf: 1561927324,
        type: "Two-Face",
        progress: "3098/4192"
      },
      Thwackville: {
        asOf: 1561927317,
        type: "Penny Pincher",
        progress: "5583/6000"
      },
      Fizzlefield: {
        asOf: 1561927328,
        type: "Loan Shark",
        progress: "678/3000"
      }
   },
   error: null
}

这是我到目前为止在Flutter应用程序中所拥有的:

class TTRAPI {
  int lastUpdated;
  final List<TTRDistrict> invasions;
  var error;

  TTRAPI({
    this.lastUpdated,
    this.invasions,
    this.error
  });


  factory TTRAPI.fromJson(Map<String, dynamic> json) {
    var invasions = json['invasions'];

    return TTRAPI(
      lastUpdated: json['lastUpdated'],
      invasions: parseDistricts(invasions),
      error: json['error']
    );
  }

  static List<TTRDistrict> parseDistricts(json) {
    List<TTRDistrict> invasions = json.map((e) => TTRDistrict.fromJson(e)).toList();
    return invasions;
  }

}

class TTRDistrict {
  int asOf;
  String type;
  String progress;

  TTRDistrict({
    this.asOf,
    this.progress,
    this.type
  });

  factory TTRDistrict.fromJson(Map<String, dynamic> json) {
    return TTRDistrict(
      progress: json['progress'],
      asOf: json['asOf'],
      type: json['type']
    );
  }
}

我遇到的所有错误都是Unhandled Exception: type '(dynamic) => TTRDistrict' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform'之类的错误。

有什么我想念的吗?我有可让我在iOS模拟器上运行的样板代码。我只是不知道JSON解析。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您可以尝试一下以了解如何实现。

import 'dart:convert';

import 'json_objects.dart';

void main() {
  final json = jsonDecode(_source) as Map<String, dynamic>;
  final response = Response1.fromJson(json);
  print('Last updated: ${response.lastUpdated}');
  final invasions = response.invasions;
  for (final key in invasions.keys) {
    final invasion = invasions[key];
    print('  $key');
    print('    ${invasion.type}');
    print('    ${invasion.progress}');
  }
}

final _source = '''
{
    "lastUpdated": 1561927328,
    "invasions": {
        "Whoosh Rapids": {
            "asOf": 1561927324,
            "type": "Two-Face",
            "progress": "3098/4192"
        },
        "Thwackville": {
            "asOf": 1561927317,
            "type": "Penny Pincher",
            "progress": "5583/6000"
        },
        "Fizzlefield": {
            "asOf": 1561927328,
            "type": "Loan Shark",
            "progress": "678/3000"
        }
    },
    "error": null
}''';

结果:

Last updated: 1561927328
  Whoosh Rapids
    Two-Face
    3098/4192
  Thwackville
    Penny Pincher
    5583/6000
  Fizzlefield
    Loan Shark
    678/3000

使用的JSON数据模型(由工具生成)

class Invasion {
  final int asOf;
  final String progress;
  final String type;

  Invasion({this.asOf, this.progress, this.type});

  factory Invasion.fromJson(Map<String, dynamic> json) {
    return Invasion(
      asOf: json['asOf'] as int,
      progress: json['progress'] as String,
      type: json['type'] as String,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'asOf': asOf,
      'progress': progress,
      'type': type,
    };
  }
}

class Response1 {
  final Object error;
  final Map<String, Invasion> invasions;
  final int lastUpdated;

  Response1({this.error, this.invasions, this.lastUpdated});

  factory Response1.fromJson(Map<String, dynamic> json) {
    return Response1(
      error: json['error'],
      invasions: _toObjectMap(json['invasions'], (e) => Invasion.fromJson(e)),
      lastUpdated: json['lastUpdated'] as int,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'error': error,
      'invasions': _fromMap(invasions, (e) => e.toJson()),
      'lastUpdated': lastUpdated,
    };
  }
}

Map<K, V> _fromMap<K, V>(data, V Function(dynamic) toJson) {
  if (data == null) {
    return null;
  }
  var result = <K, V>{};
  for (var key in data.keys) {
    V value;
    var element = data[key];
    if (element != null) {
      value = toJson(element);
    }
    result[key as K] = value;
  }
  return result;
}

Map<K, V> _toObjectMap<K, V>(data, V Function(Map<String, dynamic>) fromJson) {
  if (data == null) {
    return null;
  }
  var result = <K, V>{};
  for (var key in data.keys) {
    V value;
    var element = data[key];
    if (element != null) {
      value = fromJson(element as Map<String, dynamic>);
    }
    result[key as K] = value;
  }
  return result;
}

/*
Response1:
  "lastUpdated": int
  "invasions": Map<String, Invasion>
  "error": Object

Invasion:
  "asOf": int
  "type": String
  "progress": String
*/