LoginSignup
4
3

More than 3 years have passed since last update.

[Flutter]http通信を確立する

Last updated at Posted at 2021-05-30

dartのhttpというライブラリを用いて、Flutterのアプリでhttpの通信ができるようにします。
これによってAPIサーバーからデータを取得することができます。

20210509_03.jpg

pubspec.yamlのdependenciesに今回使うライブラリhttpを追加します。バージョンは自分の環境に合わせて変更してください。今回は記事執筆時最新のバージョンを適用します。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3 # この行を追加

flutter pub getコマンドで適用します。

flutter pub get

それではhttp通信を実装していきます。flutter createで作成したプロジェクトのコメント部分を削除したmain.dartを用意します。

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

最初にライブラリをインポートします。httpと一緒に、json形式のデータを操作するdart:convertもインポートしておきます。

main.dart
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;

次にhttp通信を実現する関数を用意します。
関数はFutureで定義します。戻り値は指定しないのでFutureとします。変数urlでAPIサーバーのurlを指定します。
無事値を取得できたら、if文内のresponse.statusCodeが200となり、今回のコードではitemCountに値を代入します。
そうでなければ、printで情報が取得できなかったことを出力します。

main.dart
 Future<void> _handleHttp() async {
   var url = Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': 'Flutter'});

   var response = await http.get(url);
   if (response.statusCode == 200) {
     var jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>;
     var itemCount = jsonResponse['totalItems'];
     print('Number of books about http: $itemCount.');
   } else {
     print('Request failed with status: ${response.statusCode}.');
   }
 }

それでは作成した関数の動作確認を行います。
main.dartのfloatingActionButtonを書き換えます。onPressedの値を_handleHttpにして、ボタンを押したらAPIサーバーに情報を受け取りにいくようにします。

main.dart
floatingActionButton: FloatingActionButton(
  onPressed: _handleHttp,
  tooltip: 'Increment',
  child: Icon(Icons.add),
), 

以下、書き換えたコードの全体を記します。

main.dart
import 'package:flutter/material.dart';

import 'dart:convert' as convert;
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<void> _handleHttp() async {
    // This example uses the Google Books API to search for books about http.
    // https://developers.google.com/books/docs/overview
    var url = Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': 'Flutter'});

    // Await the http get response, then decode the json-formatted response.
    var response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>;
      var itemCount = jsonResponse['totalItems'];
      print('Number of books about http: $itemCount.');
    } else {
      print('Request failed with status: ${response.statusCode}.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _handleHttp,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

ボタンを押したら、コンソールにAPIサーバーから取得した値が表示されます。

I/flutter ( 1572): Number of books about http: 669.

せっかくなので、APIサーバーから取得した値をアプリ上で表示できるようにします。_MyHomePageStateに_wordを追加し、ボタンを押してら_wordの値が書き変わるようにしました。

main.dart
import 'package:flutter/material.dart';

import 'dart:convert' as convert;
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String _word = '';

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<void> _handleHttp() async {
    var url = Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': 'Flutter'});

    var response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>;
      var itemCount = jsonResponse['totalItems'];
      print('Number of books about http: $itemCount.');
      setState(() {
        _counter = itemCount;
        _word = 'Flutter';
      });
    } else {
      print('Request failed with status: ${response.statusCode}.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '「$_word」の検索結果:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _handleHttp,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

以下、実際に動かしたアプリの画面です。

ボタンを押す前

20210509_01.jpeg

ボタンを押した後

20210509_02.jpeg

以上、dartのライブラリhttpを用いて、APIサーバーから値を取得するコードでした。

APIの通信にはDioというライブラリを使う方法もあるようなので、いずれDioも試してみたいと思います。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3