【Flutter/Dart】shared_preferencesでローカルにデータを保存する方法と仕組み

【Flutter/Dart】shared_preferencesでローカルにデータを保存する方法と仕組み

この記事からわかること

  • Flutter/Dartshared_preferences実装方法
  • ローカルデータ保存するには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Flutterアプリで端末(ローカル)にデータを永続的に保存する方法

FlutterでiOS/Androidアプリを開発する際に端末(ローカル)にデータを永続的に保存する方法はいくつか用意されています。

それぞれに一長一短がありますが今回はshared_preferencesを使用する方法をまとめていきます。

shared_preferences

公式リファレンス:shared_preferences

shared_preferencesローカルにデータを保存するための機能を提供しているパッケージです。独自の仕組みというよりiOS/Android固有の永続ストレージ機能をラップして共通して実装できるようになっているのがこのパッケージです。

iOSはUserDefaults、AndroidはSharedPreferencesの仕組みがラップされています。ラップしているだけなので仕組みはそれぞれの要件を確認する必要がありますが、データを永続化できること大事なデータ(ログイン情報など)は格納しないという点は共通かと思います。

ログイン情報などのセキュリティ要件を高めて保存したいデータflutter_secure_storageを活用してください。こちらはiOSはKeyChain、AndroidはKeyStoreをラップしたパッケージになります。

サポートされているデータ型はintdoubleboolStringList<String>です。

導入方法

パッケージを導入するにはプロジェクトルートでflutter pub add パッケージ名コマンドを実行します。

$ flutter pub add shared_preferences

これでパッケージの導入が完了し、import文を追加すれば使用できるようになります。

import 'package:shared_preferences/shared_preferences.dart';

実装方法

shared_preferencesを使用するにはまずSharedPreferencesインスタンスを取得する必要があります。シングルトンのインスタンスがgetInstanceメソッドで取得できるのこれを使用して取得します。ただasyncが付与されている非同期処理になるのでawaitを使用して呼び出す必要があるので注意してください。

final prefs = await SharedPreferences.getInstance();

データを保存する

データを保存したい場合setデータ型(キー,値)メソッドを使用します。引数にデータを保存するためのキー実際に保存したい値を指定します。こちらもasyncが付与されている非同期処理になるのでawaitを使用して呼び出す必要があります。

final prefs = await SharedPreferences.getInstance();
await prefs.setString(SharedPreferencesKeys.USERNAME.key, 'ame');

データ型によって呼び出すメソッドが変化します。

メソッド名 データ型
setInt(String key, int value) int
setDouble(String key, double value) double
setBool(String key, bool value) bool
setString(String key, String value) String
setStringList(String key, List<String> value) List<String>

データを取得する

データを取得したい場合getデータ型(キー)メソッドを使用します。引数にデータを取得するためのキーを指定します。こちらは非同期ではないのでawaitを使用せずに呼び出すことが可能です。

final prefs = await SharedPreferences.getInstance();
String? username = prefs.getString(SharedPreferencesKeys.USERNAME.key);
print(username);

またデータが存在しなかった場合nullが返却されます。データ型によって呼び出すメソッドが変化します。

メソッド名 データ型
getInt(String key) int?
getDouble(String key) double?
getBool(String key) bool?
getString(String key) String?
getStringList(String key) List<String>?

データを削除する

一度保存したデータはアプリがアンインストールされない限り永続化されます。データを明示的に削除したい場合remove(キー)メソッドを使用します。また全てのデータを削除したい場合はclearメソッドを使用します。

// 指定して削除
await prefs.remove(SharedPreferencesKeys.USERNAME.key);
// 全て削除 
await prefs.clear();
メソッド名 データ型 説明
remove(String key) Future<bool> 指定したキーのデータを削除する
clear() Future<bool> すべてのデータを削除する

管理クラスに切り出してみる

ローカル保存・取得の機能を管理用クラスとして切り出してみました。_instanceからシングルトンインスタンスを参照できるようになっており、キーはSharedPreferencesKeysで管理しています。


import 'package:shared_preferences/shared_preferences.dart';

enum SharedPreferencesKeys {
  USERNAME('username');

  final String key;
  const SharedPreferencesKeys(this.key);
}

class SharedPreferencesService {
  static final SharedPreferencesService _instance = SharedPreferencesService._internal();
  factory SharedPreferencesService() => _instance;
  SharedPreferences? _prefs;

  SharedPreferencesService._internal();

  Future<void> init() async {
    _prefs = await SharedPreferences.getInstance();
  }

  Future<void> saveUsername(String username) async {
    _prefs?.setString(SharedPreferencesKeys.USERNAME.key, username);
  }

  String? getUsername() {
    return _prefs?.getString(SharedPreferencesKeys.USERNAME.key);
  }

  Future<void> remove(SharedPreferencesKeys key) async {
    final prefs = _prefs;
    if (prefs == null) return;
    await prefs.remove(key.key);
  }

  Future<void> clearData() async {
    final prefs = _prefs;
    if (prefs == null) return;
    await prefs.clear();
  }
}

実際にViewから使用する場合は以下のように使用します。

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SharedPreferencesService().init();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const PageA(),
    );
  }
}

class PageA extends StatefulWidget {
  const PageA({super.key});

  @override
  State<PageA> createState() => _PageAState();
}

class _PageAState extends State<PageA> {
  String _username = "";
  TextEditingController _controller = TextEditingController();

  // ユーザー名を取得
  Future<void> _getUsername() async {
    String? username = SharedPreferencesService().getUsername();
    setState(() {
      _username = username ?? "まだ保存されていません";
    });
  }

  // ユーザー名を保存
  Future<void> _saveUsername() async {
    String username = _controller.text; // 入力されたユーザー名を取得
    if (username.isNotEmpty) {
      await SharedPreferencesService().saveUsername(username);
      _getUsername(); // 保存後に再取得
    } else {
      // 空のユーザー名が入力された場合はアラート
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("ユーザー名を入力してください")),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("SharedPreferences デモ")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 入力ボックス
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: TextField(
                controller: _controller,
                decoration: const InputDecoration(
                  labelText: "ユーザー名を入力",
                  border: OutlineInputBorder(),
                ),
              ),
            ),
            const SizedBox(height: 20),

            // 保存されているユーザー名表示
            Text(
              "保存されているユーザー名: $_username",
              style: const TextStyle(fontSize: 18),
            ),
            const SizedBox(height: 20),

            // ユーザー名取得ボタン
            ElevatedButton(
              onPressed: _getUsername,
              child: const Text("ユーザー名を取得"),
            ),
            const SizedBox(height: 20),

            // ユーザー名保存ボタン
            ElevatedButton(
              onPressed: _saveUsername,
              child: const Text("ユーザー名を保存"),
            ),
          ],
        ),
      ),
    );
  }
}
【Flutter/Dart】shared_preferencesでローカルにデータを保存する方法と仕組み

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index