FlutterでJSONを詰め込むための構造体を簡単に作る方法

markdown-img-paste-20210529220151451.webp
目次

はじめに

Flutterアプリ開発では、JSONデータを取得し、Dartの構造体に変換することがよくあります。そんな時に役立つツール「JSON to Dart」をご紹介し、郵便番号検索APIを例に実際に使ってみたいと思います。

JSON to Dartの使い方

ここでは、JSON to Dartを使って取得したJSONデータをDartの構造体に変換する方法を説明します。

JSON to Dart

JsonファイルからそのJsonをDart構造体に詰め込むことができるコードを生成するサイトです。 これを使うことで、Jsonを取得できるWEBAPIを使ったアプリ開発がめっちゃやりやすくなります。

JSONデータの取得と変換

まずは郵便番号検索APIからJSONデータを取得し、JSON to Dartを使ってDartの構造体に変換します。変換後のコードはjson/JsonStruct.dartに配置されます。

https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060

取得したJsonをJson to Dartにかけていきます。

{
    "message": null,
    "results": [
        {
            "address1": "高知県",
            "address2": "南国市",
            "address3": "蛍が丘",
            "kana1": "コウチケン",
            "kana2": "ナンコクシ",
            "kana3": "ホタルガオカ",
            "prefcode": "39",
            "zipcode": "7830060"
        }
    ],
    "status": 200
}

コード解説

この記事で紹介したコードは、以下のような構成になっています。

json/JsonStruct.dart: JSON to Dartで生成したDart構造体のコード models/logic.dart: APIからJSONデータを取得し、Dart構造体に変換するロジック view/ui.dart: 取得したデータを表示するUIコンポーネント

フォルダ構成

C:.
│  main.dart
│
├─json
│      JsonStruct.dart
│
├─models
│      logic.dart
│
└─view
        ui.dart

json/JsonStruct.dart

ツールをかけて取得結果を貼り付け、一部コードを修正します。 (Null Safetyなどの兼ね合いで最新のDartだとエラーが出るため)

ほとんど変換しただけですが、とりあえず貼り付けます。

class Autogenerated {
  Null message;
  late List<Results> results;
  late int status;

  Autogenerated({this.message, required this.results, required this.status});

  Autogenerated.fromJson(Map<String, dynamic> json) {
    message = json['message'];
    if (json['results'] != null) {
      results = <Results>[];
      json['results'].forEach((v) {
        results.add(new Results.fromJson(v));
      });
    }
    status = json['status'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['message'] = this.message;
    data['results'] = this.results.map((v) => v.toJson()).toList();
    data['status'] = this.status;
    return data;
  }
}

class Results {
  String? address1;
  String? address2;
  String? address3;
  String? kana1;
  String? kana2;
  String? kana3;
  String? prefcode;
  String? zipcode;

  Results(
      {required this.address1,
      required this.address2,
      required this.address3,
      required this.kana1,
      required this.kana2,
      required this.kana3,
      required this.prefcode,
      required this.zipcode});

  Results.fromJson(Map<String, dynamic> json) {
    address1 = json['address1'];
    address2 = json['address2'];
    address3 = json['address3'];
    kana1 = json['kana1'];
    kana2 = json['kana2'];
    kana3 = json['kana3'];
    prefcode = json['prefcode'];
    zipcode = json['zipcode'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['address1'] = this.address1;
    data['address2'] = this.address2;
    data['address3'] = this.address3;
    data['kana1'] = this.kana1;
    data['kana2'] = this.kana2;
    data['kana3'] = this.kana3;
    data['prefcode'] = this.prefcode;
    data['zipcode'] = this.zipcode;
    return data;
  }
}

APIからのJSONデータ取得

models/logic.dartにAPIからJSONデータを取得するコードを実装します。http.Responseを使って指定したURLからJSONデータを取得し、JSON to Dartで作成したAutogeneratedクラスのfromJson()で構造体に変換します。

strtmp変数はchangeNotifyしたあとUIから読み出すための変数です。 取り出した値の一部を格納します。

void requestSample() async {
    var uri =
            Uri.parse('https://zipcloud.ibsnet.co.jp/api/search?zipcode=0791100');

    http.Response res = await http.get(uri);
    if (res.statusCode == 200) {
        String data = res.body;
        Map<String, dynamic> map = jsonDecode(data);
        var human = Autogenerated.fromJson(map);
        // String address1 = map['results'][0]['address1'];
        strtmp = human.results[0].address1!;
        print(human.results[0].address1);
    } else {
        throw Exception('Failed to load post');
    }
}

UIの実装

view/ui.dartでは、UI用のStatelessWidgetを作成し、取得したデータを表示するTextウィジェットを実装します。

前回記事と同様にUI用のStatelessWidgetを作っていきます。 中身はTextで先程詰め込んだstrtmpの値が更新されたら描画しています。

class PostcodeAddress extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      /// context からModelの値が使える
      '${Provider.of<CountModel>(context).strtmp}',
      style: Theme.of(context).textTheme.headline4,
    );
  }
}

全部コードを置いていく

正直上に書いたコードとimportだけで十分ですが、 前回の書いた記事のコードをベースに分離しているのでそのままです。

Provider Patternを使い、FlutterアプリUIとロジックを分離するための考察

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'package:mvvm_hotpepper/json/JsonStruct.dart';

class CountModel extends ChangeNotifier {
  /// 初期値
  int count = 0;
  String address = "ウマ娘";
  String res = "";

  String strtmp = "";

  /// count の更新メソッド
  void increment() {
    count++;
    changeText();
    requestSample();
    notifyListeners();
  }

  void changeText() {
    if (count > 5) {
      address = "ウマ娘プリティーダービー";
    }
  }

  void requestSample() async {
    var uri =
        Uri.parse('https://zipcloud.ibsnet.co.jp/api/search?zipcode=0791100');

    http.Response res = await http.get(uri);
    if (res.statusCode == 200) {
      String data = res.body;
      Map<String, dynamic> map = jsonDecode(data);
      var human = Autogenerated.fromJson(map);
      // String address1 = map['results'][0]['address1'];
      strtmp = human.results[0].address1!;
      print(human.results[0].address1);
    } else {
      throw Exception('Failed to load post');
    }
  }
}

ツールの実行結果

右下の虫眼鏡アイコンを叩くと結果のような値が取得できます。 今は、URLに郵便番号直打ちですがInputボックスなどと組み合わせれば郵便番号検索ができます。 ちなみに、画面描画の都合上虫眼鏡を2回クリックしないと住所が出ないですが…まぁ些細な話ですよ。

まとめ

この記事では、JSON to Dartを使ってFlutterアプリでJSONデータを取得し、Dartの構造体に変換する方法を説明しました。これを使えば、様々なAPIからデータを取得してFlutterアプリで利用できるようになります。また、UIとロジックが分離されているため、中規模のコードも作成できそうです。

Related Post

> FlutterでJSONを詰め込むための構造体を簡単に作る方法
FlutterでProviderパターンを使ってUIとロジックを分離する方法
> FlutterでJSONを詰め込むための構造体を簡単に作る方法
AndroidのGPSから現在地を取得しGoogle Map上で表示するFlutterアプリ
> FlutterでJSONを詰め込むための構造体を簡単に作る方法
FlutterでGoogle Mapにマーカーを追加する方法
> FlutterでJSONを詰め込むための構造体を簡単に作る方法
FlutterでGoogle Mapのパラメータを変更して遊んでみよう
> FlutterでJSONを詰め込むための構造体を簡単に作る方法
FlutterでGoogleマップを表示する方法
> FlutterでJSONを詰め込むための構造体を簡単に作る方法
Flutter Studioを使ってこなれたUIを作ってみよう。

おすすめの商品

>