はじめに
Flutterで開発していく中で、キャッシュが必要な仕様に直面しました。
そこで、色々なキャッシュを実装しましたので、その方法を記します。
キャッシュを保存する場所
キャッシュを保存する場所によって、実装が異なります。
なので、ここでは、キャッシュを保存する場所を列挙します。
(1) メモリ
Flutterの変数に保存する方法です。
メリット
- Read/Writeが速い。
- データが扱いやすい。
デメリット
- アプリを終了した場合、破棄される。
- ネイティブプラットフォーム(Android/iOS)と共有しにくい。
(2) ファイルシステム
ローカルにファイルとして保存する方法です。
メリット
- アプリを終了しても破棄されず、次回起動時も保持される。
- ネイティブプラットフォーム(Android/iOS)と共有しやすい。
デメリット
- Read/Writeが遅い。
- データが扱いにくい。
(3) データベース
ローカルのデータベースに保存する方法です。
メリット
- アプリを終了しても破棄されず、次回起動時も保持される。
- データが扱いやすい。
デメリット
- Read/Writeが遅い。
- 使用するデータベースによって、ネイティブプラットフォーム(Android/iOS)と共有しにくいorできない。
(1) メモリにキャッシュする実装方法
色々な実装方法があると思います。
その中で、自分が実装した方法を記します。
それは、Singleton Patternを用いた方法です。
class CacheClass {
// Singleton Patternを実現
static final CacheClass _instance = CacheClass._internal();
CacheClass._internal();
factory CacheClass() => _instance;
// キャッシュで保持するデータ
late Object data;
}
Singletonを用いる事で、どこからでも、同一のデータにアクセスできます。
どのdartファイルからでも。
どのインスタンスからでも。
どの関数からでも。
そのアクセス方法です。
void main() {
// キャッシュにWrite
CacheClass().data = "Hello World!";
// キャッシュをRead
print(CacheClass().data);
}
Hello World!
(2) ファイルシステムにキャッシュする実装方法
実装方法は、おおよそ1つだと思います。
【追記(2021/12/20)】
他の実装方法を見つけました。
"shared_preferences"を用いる方法です。実装方法は割愛します。
import 'dart:async'; // 非同期処理用ライブラリ
import 'dart:io'; // ファイル出力用ライブラリ
import 'package:path_provider/path_provider.dart'; // ファイルを保存可能な場所を取得するライブラリ
// ファイルを保存するパスを取得する
Future<File> getFilePath(String fileName) async {
final directory = await getApplicationDocumentsDirectory();
return File(directory.path + '/' + fileName);
}
// テキストファイルの読み込み
Future<String> readTxtFile(String fileName) async {
final file = await getFilePath(fileName);
return file.readAsString();
}
// テキストファイルの書き込み
Future<void> writeTxtFile(String fileName, String data) async {
final file = await getFilePath(fileName);
file.writeAsString(data);
}
// バイナリファイルの読み込み
Future<List<int>> readBinaryFile(String fileName) async {
final file = await getFilePath(fileName);
return file.readAsBytes();
}
// バイナリファイルの書き込み
Future<void> writeBinaryFile(String fileName, List<int> data) async {
final file = await getFilePath(fileName);
file.writeAsBytes(data);
}
ネイティブプラットフォーム(Android/iOS)も、
ローカルファイルへアクセスする事は簡単だと思うので、キャッシュの共有が楽です。
(3) データベースにキャッシュする実装方法
色々なデータベースを使う方法があると思います。
以下の記事に、Flutterで使えるデータベースについて纏められてます。
その中で、自分が実装した方法を記します。
私は、Hiveを使いました。
Fast, Enjoyable & Secure NoSQL Database
高速で楽しく安全なNoSQLデータベース
Hive is a lightweight and blazing fast key-value database written in pure Dart. Inspired by Bitcask.
Hiveは、純粋なDartで記述された軽量で非常に高速なKey-Valueデータベースです。 Bitcaskに触発されました。
実装は非常に簡単です。
void main() async {
// DBを生成
var box = await Hive.openBox('myBox');
// DBへデータ追加
box.put('name', 'David');
// DBからデータ取得
var name = box.get('name');
}
また、自前で作成したデータクラスを扱う事も可能です。
補足
ネイティブプラットフォーム(Android/iOS)との共有は出来ません。
(ネイティブプラットフォームとの共有が必要な場合は、中々ないと思います。。)
また、高速性をアピールしてるだけあって、非常に高速です。
さいごに
やってみた感想です。
色々なキャッシュがあるものの、その実装方法はどれも簡単でした
特にHiveは気に入りました! 実装は簡単、処理は高速。良いことづくめですね
キャッシュは、だいたいのアプリで必須だと思うので、参考になれば幸いです!
では