【Flutter】人気なパッケージの使い方 〜shared_preferences編〜

## まえがき
2020年が始まってからFlutterを勉強始めました。

自分で試しにチャットアプリを開発してみたりしています。
いろんなパッケージがあり、どんどん使ってみたいなと思い始めてます。

とりあえず勉強するために、公式ドキュメントにある「Flutter Favorite」なパッケージから勉強してみることにしました。

まずは**shared_preferences**を使ってみます。

これまで載せた記事
- [shared_preferencesの紹介](https://qiita.com/ryota47/items/bc381f85080dbf4b2454)←今これ
- [url_launcherの紹介](https://qiita.com/ryota47/items/0cd30257f063c06df1b8)
- [flutter_slidableの紹介](https://qiita.com/ryota47/items/6ed90ce011ea6aaa8698)

## shared_preferences
shared_preferencesはデータをプラットフォーム固有の永続ストレージに保存することができるパッケージ

- String
- Int
- Bool
- Double
- key?

が保存できる
- `getString`で読み込み
- `setString`で書き込み
- `remove`で削除
することができる。

`getInt`と`setInt`は非同期処理が必要であり、Future/async/awaitを使い関数を作成する。


永久ストレージに保存されるため、一度保存すれば、どのクラスやWidgetからでも取得ができる。
もちろんビルドしなおしてもその値が保持されます。

## サンプル

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311390/6c7d9655-303f-a07e-75a1-a698156e9c64.gif)

試しに、フォームで名前を入力するとその名前が表示されると言うサンプルを作成しました。
**shared_preferences**を使うことで、リビルドされても最後に入力した名前は保存されているため、表示されるようになっています。



```dart
import 'package:shared_preferences/shared_preferences.dart';

import 'package:flutter/material.dart';

class SampleSharedPreferences extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SampleSharedPreferences();
}

class _SampleSharedPreferences extends State<SampleSharedPreferences> {
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  final _nameController = TextEditingController();
  String _name;

  @override
  void initState() {
    super.initState();
    getName().then((value) {
      setState(() {
        _name = value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('shared_preferences'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                '$_name',
                style: TextStyle(fontSize: 32),
              ),
              TextFormField(
                controller: _nameController,
                decoration: InputDecoration(hintText: '名前を入力してね'),
              ),
              RaisedButton(
                child: Text('保存'),
                onPressed: () {
                  setName().then((success) {
                    _nameController.clear();
                  });
                },
              ),
              RaisedButton(
                child: Text('削除'),
                onPressed: () {
                  removeName();
                },
              ),
            ],
          ),
        ));
  }

  setName() async {
    SharedPreferences prefs = await _prefs;
    prefs.setString('name', _nameController.text);
    setState(() {
      _name = prefs.getString('name');
    });
  }

  getName() async {
    SharedPreferences prefs = await _prefs;
    return prefs.getString('name');
  }

  removeName() async {
    SharedPreferences prefs = await _prefs;
    prefs.remove('name');
    setState(() {
      _name = null;
    });
  }
}

```

## 説明
`initState()`で`getName()`が動きます。
`getString`で永久ストレージから取得し、`_name`に入れます。


「保存 」ボタンを押すと`setName()`と言う関数が、動く。
`prefs.setString('name', _nameController.text);`この文で、永久ストレージに`name`という名前で`_nameController.text`を書き込んでる。

`setState((){})`で名前を`_name`に名前を入れます。
```
setState(() {
  _name = _nameController.text;
});
```

これでも問題ないのですが、今回は**shared_preferences**を意識するために`getString`を使いました。

`removeName()`は永久ストレージのデータを削除する関数です。
`prefs.remove('name')`で消しています。
`_name`もnullにしておきます。


簡単にですがこんな感じ


### 思いつく使い道
何回も使うけどいちいちFirestoreなどから取得するとめんどくさいものを書き込みしておく
currentUserのIDやデバイスのトークンとかを保存すればいいかな〜