(当頁はdocs.flutter.dev(https://docs.flutter.dev/cookbook/persistence/key-value)のリファレンスブログです。)
1.概要
Flutterアプリで、比較的小規模なキーと値のデータを保存したい場合、shared_preferences プラグインを利用できます。
通常、データを保存するためには、各プラットフォーム(iOS、Androidなど)ごとにネイティブコードを書く必要があります。しかし、shared_preferences プラグインを使えば、Flutterがサポートするすべてのプラットフォームでキーと値のデータを簡単にディスク上に保存できます。
2.SharedPreferences依存関係の追加
shared_preferences プラグインをプロジェクトに追加します。
flutter pub add shared_preferences
3.SharedPreferencesでデータを永続化する方法
SharedPreferencesクラスは、アプリのローカルストレージにデータを永続的に保存するためのメソッドを提供しています。
(保存メソッド)
- setInt: 整数値を保存する。
- setBool: 真偽値(true または false)を保存する。
- setString: 文字列を保存する。
- 他にも setDouble や setStringList といったメソッドがあります。
- これらのメソッドは、指定したキー(key)に基づいてデータを保存します。
//アプリ用の SharedPreferences インスタンスを取得
final prefs = await SharedPreferences.getInstance();
//カウンター値を 'counter' というキーで保存
await prefs.setInt('counter', counter);
(保存メソッドの動作)
- メモリ上でキーと値を即座に更新
- 保存操作が呼び出されると、即座にメモリ上でデータが更新されます。
- 保存操作が呼び出されると、即座にメモリ上でデータが更新されます。
- ディスクへの永続化
- メモリ上の更新後、データを非同期でディスクに保存します。
- 保存されたデータは、次回アプリ起動時にも利用可能です。
(注意点)
- 保存されたデータは小規模なデータ向けです。大きなデータや複雑な構造体には適していません。
- 非同期処理のため、保存処理が完了する前に次のコードを実行しないように注意する必要があります。
4.SharedPreferencesでデータを読み込む方法
SharedPreferencesクラスは、ローカルストレージから保存されたデータを読み込むためのメソッドを提供しています。
(取得メソッド)
- getInt: 整数値を取得する。
- getBool: 真偽値(true または false)を取得する。
- getString: 文字列を取得する。
- 他にも getDouble や getStringList といったメソッドがあります。
- これらのメソッドは、指定したキー(key)を使用してデータを検索します。
// SharedPreferences のインスタンスを取得
final prefs = await SharedPreferences.getInstance();
// 永続ストレージから 'counter' キーに対応する値を取得
// 値が存在しない場合は null が返されるため、デフォルト値として 0 を指定
final counter = prefs.getInt('counter') ?? 0;
(getter メソッドの動作)
- 対応する型のメソッドを使用
- setInt で保存されたデータは、getInt を使用して取得します。
- setInt で保存されたデータは、getInt を使用して取得します。
- 型の不一致に注意
- 保存されたデータの型がメソッドで期待される型と異なる場合、例外がスローされます。
- 例: setString で保存されたデータに対して getInt を使用するとエラーになります。
(注意点)
- 型の不一致に注意
- getInt で文字列を取得しようとすると例外が発生します。保存時と同じ型を指定して下さい。
- getInt で文字列を取得しようとすると例外が発生します。保存時と同じ型を指定して下さい。
- デフォルト値を設定
- 値が存在しない場合のために、??演算子を使ってデフォルト値を指定するのが一般的です。
5.SharedPreferencesでデータを削除する
SharedPreferencesクラスは、保存されたデータを削除するための便利なremove()メソッドを提供しています。
このメソッドを使用することで、特定のキーに対応する値を永続ストレージから削除できます。
(remove() メソッドの概要)
- remove(String key)
- 指定したキーに関連付けられたデータを削除します。
- 削除後、そのキーは存在しない状態になり、次回アクセス時にはnullを返します。
//SharedPreferences のインスタンスを取得
final prefs = await SharedPreferences.getInstance();
//キー 'counter' に関連するデータを削除
await prefs.remove('counter');
(注意点)
- 特定のキーのみ削除
- remove()は指定されたキーに対応するデータのみを削除します。他のデータは影響を受けません。
- remove()は指定されたキーに対応するデータのみを削除します。他のデータは影響を受けません。
- すべてのデータを削除する場合
- すべてのデータを削除したい場合は、clear()メソッドを使用します。
6.サポートされるデータ型
shared_preferencesは便利なキー・バリュー型のストレージを提供しますが、いくつかの制限があります。
特に、保存できるデータ型やデータの扱い方に関して制限があるため、使用する際にはその特性を理解しておく必要があります。
6.1 保存できるデータ型
shared_preferencesは以下のようなプリミティブ型をサポートしています。
(1)int:
整数値を保存できます。
例: カウンタやユーザーIDなど。
await prefs.setInt('key', 123);
final value = prefs.getInt('key') ?? 0; // 123
(2)double:
浮動小数点数を保存できます。
例: 設定値や座標など。
await prefs.setDouble('key', 3.14);
final value = prefs.getDouble('key') ?? 0.0; // 3.14
(3)bool:
真偽値を保存できます。
例: 設定のオン/オフ。
await prefs.setBool('key', true);
final value = prefs.getBool('key') ?? false; // true
(4)String:
文字列を保存できます。
例: ユーザー名やトークンなど。
await prefs.setString('key', 'Hello');
final value = prefs.getString('key') ?? ''; // Hello
(5)List:
文字列のリストを保存できます。
例: 履歴や選択項目リスト。
await prefs.setStringList('key', ['One', 'Two', 'Three']);
final value = prefs.getStringList('key') ?? []; // ['One', 'Two', 'Three']
6.2 制限事項
(1)プリミティブ型以外は保存できない
shared_preferencesはプリミティブ型(int, double, bool, String, List)に限定されており、オブジェクトや複雑な構造は直接保存できません。オブジェクトを保存する場合、JSON形式などに変換して保存する必要があります。
//オブジェクトをJSON形式の文字列に変換して保存
final user = {'name': 'John', 'age': 30};
await prefs.setString('user', jsonEncode(user));
//保存したJSONをデコードして復元
final userString = prefs.getString('user');
final userMap = jsonDecode(userString ?? '{}');
print(userMap['name']); // John
(2)大量のデータの保存には不向き
shared_preferencesは小規模なデータ(設定値やトークンなど)を保存するためのもので、大量のデータやバイナリデータの保存には適していません。大量のデータを扱う場合は、データベース(sqfliteなど)やファイルシステムを使用することが推奨されます。
(3)アプリ再起動時にデータが確実に保持される保証はない
データの永続性が保証されない場合があります。
アプリがアンインストールされたり、特定の条件下でデータが消失する可能性があります。
7.テストサポート
8.サンプルコード
import 'package:flutter/material.dart';
//shared_preferences パッケージ:
//( データをデバイスのローカルストレージに保存し、永続化を実現します。)
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Shared preferences demo',
home: MyHomePage(title: 'Shared preferences demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
@override
void initState() {
super.initState();
_loadCounter();
}
//カウンター値のロード:
//( アプリ起動時、SharedPreferencesからカウンター値を取得します。
// 保存された値が存在しない場合はデフォルト値0を使用します。
// setState() を使って、取得した値を画面に反映します。)
Future<void> _loadCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = prefs.getInt('counter') ?? 0;
});
}
//カウンター値のインクリメントと保存:
//( ボタンを押すと、現在のカウンター値をインクリメントします。
// 更新された値をshared_preferencesに保存します。)
Future<void> _incrementCounter() async {
//SharedPreferences.getInstance():
//( 非同期でストレージにアクセスし、インスタンスを取得します。)
final prefs = await SharedPreferences.getInstance();
setState(() {
//prefs.getInt('counter'):
//( 保存されたcounterキーの値を取得します。)
_counter = (prefs.getInt('counter') ?? 0) + 1;
//prefs.setInt('counter', _counter):
//( 現在のカウンター値をshared_preferencesに保存します。)
prefs.setInt('counter', _counter);
});
}
//UIの構築:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
//画面の中央に、現在のカウンター値を表示します。
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'You have pushed the button this many times: ',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
//FloatingActionButton を押すと、カウンター値がインクリメントされます。
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
(実行結果の例)
- アプリ起動時に保存されたカウンター値が復元されます。
- ボタンを押すとカウンターが増加し、現在の値がローカルストレージに保存されます。
- アプリを閉じても、次回起動時に前回のカウンター値が画面に表示されます。
このコードは、shared_preferencesを使った基本的なキーと値の永続化の例であり、小規模な設定やユーザのデータを保存するのに最適です。