LoginSignup
13
2
お題は不問!Qiita Engineer Festa 2023で記事投稿!

[Flutter]ネイティブアプリで保存した値を取得するためには??

Posted at

スクリーンショット 2023-07-10 10.25.29(2).png

こんにちわ。

今回はFlutterを勉強している中で「え!知らなかった!?!?」 ということがありましたので共有したいと思います。

ちょっとしたデータをローカルに保存したい場合は、Shared PreferencesというFlutter公式のプラグインを使用することで簡単に実現できます。例えばアプリに関する設定情報などのデータを保存したい場合に便利です!

そんな便利なShared Preferencesですが、落とし穴があったので書いていこうと思います!!

プロフィール

スクリーンショット 2023-06-13 7.33.21(2).png

shared_preferencesとは

 shared_preferencesでは、Flutterで作成したアプリ内で、データを保存したり読み出したりできます。

 データは非同期でディスクに保存される可能性があり、書き込みが戻った後にディスクに保存されるという保証はないため、このプラグインは重要なデータの保存には適さないそうです。

こんな場面で使用されることが多いです。

  • テーマのダークモードやライトモード
  • 言語設定
  • 状態の保存
iOSエンジニアの方にもわかりやすく説明すると
  • iOSでいうとUserDefaultsにあたる。
  • データの保存場所としては/AppData/Library/Preferences/に格納されるらしいです。

(間違っていたら教えてください😀)

Androidエンジニアの方にもわかりやすく説明すると
  • Androidで言うとSharedPreferencesにあたる。
  • データの保存場所としては/data/data/<your app package name>/shared_prefs/に格納されるらしいです。

(間違っていたら教えてください😀)

shared_preferencesではダメなのか

結論から言います。ダメではないのですが、場合によっては、保存/取得ができないトラブルがあります。
その場合の例として、ネイティブアプリ(iOS/Android)をリプレイスするときに、保存していたローカルデータは取得することができません。

bikkuri_me_tobideru_man.png

その理由としては、shared_preferencesでは保存・取得の際にflutter.というプレフィックス(その単語なり何なりの前(頭)にくっつく文字のこと)をキーに付与してデータを扱っているからです。

例えば、

class Preference {
  static const _key = 'preference';
  
  Future<bool> get() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool(_key) ?? false;
  }

  Future<bool> set() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.setBool(_key, true);
  }

このコードでは取得(get)・保存(set)をしているコードです。
ここでは、_keyは、preferenceにしていますが、実際には、flutter.preferenceというキーで値を取得・保存しています。

flutterのみでは問題はありませんが、ネイティブで保存された値のキーは、プレフィックス(flutter.)なしで保存されているため、shared_preferencesで取得しようとすると、取得ができません。

shared_preferenceの中身を見てみると。。。

一部抜粋
static const String _prefix = 'flutter.';

Future<bool> _setValue(String valueType, String key, Object value) {
    final String prefixedKey = '$_prefix$key';
    if (value == null) {
      _preferenceCache.remove(key);
      return _store.remove(prefixedKey);
    } else {
      if (value is List<String>) {
        _preferenceCache[key] = value.toList();
      } else {
        _preferenceCache[key] = value;
      }
      return _store.setValue(valueType, prefixedKey, value);
    }
  }

Future<bool> setBool(String key, bool value) => _setValue('Bool', key, value);

Flutter・・・flutter.preference

ネイティブ・・・preference

となり、うまく取得できない問題があります。
このような問題は、ネイティブ→Flutterでのリプレイスなどで起こる問題なので普段はあまりないとは思うので、なかなか調べられている記事が少なかったです。(^^;;

解決策

色々あると思いますが、native_shared_preferencesのパッケージを使用した方が良さそうです。

native_shared_preferencesを使うことで、ネイティブからプレフィックスなしで値を取って来れます。

ただ、注意点として

  • 以前のネイティブアプリバージョンからの取得のみに使用の方が良さそう。
  • 移行の管理をする場合には、version_migrationを使用した方が良さそう。
  • 実際にマイグレーションする際には正確に値が移行できているかテストした方がいい。

最後に

このようなトラブルは多くはないのですが、一つの知識として知っておくといいと思います!

ps:7月8日に親友とディズニーランドに行きました!40周年のパレードを初めてみれてとても幸せでした。さらに最近はキャラクターとハグが解禁されて、推しのファンタジアミッキーとハグができてハッピーでした😀

参考文献

13
2
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
13
2