こんにちは。広瀬マサルです。
後々リリース予定の総合フレームワークのために利用されるパッケージをいくつか紹介します。
今回はファイルストレージ周りのパッケージとなります。
Cloud Storage for Firebaseを後々利用するためのテスト用のパッケージとなります。
使い方をまとめたので興味ある方はぜひ使ってみてください!
katana_storage
はじめに
画像ファイルを代表したファイルをアップロードする機能は様々なアプリで利用されます。
SNSやマッチングアプリなど画像ファイルをアップロードすることでコミュニケーションを円滑にすることが可能です。
ファイルをアップロードしてアプリで利用可能にするクラウドサービスは数多くありますが、Flutterを利用しかつFirestoreなどを利用している場合はCloud Storage for Firebaseを利用することが最も適しているかと思います。
このパッケージではkatana_modelで実装したときと同じ様にアダプターを利用してFirebaseやローカルでのファイルストレージを切り替えることが可能になるようなパッケージを実装しました。
インストール
下記パッケージをインポートします。
flutter pub add katana_storage
Cloud Storage for Firebaseを利用する場合は下記のパッケージを合わせてインポートします。
flutter pub add katana_storage_firebase
実装
事前準備
必ずStorageAdapterScope
のWidgetをアプリのルート近くに配置します。
adapterのパラメーターにLocalStorageAdapter
といったStorageAdapterを渡します。
// main.dart
import 'package:flutter/material.dart';
import 'package:katana_storage/katana_storage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return StorageAdapterScope(
adapter: const LocalStorageAdapter(),
child: MaterialApp(
home: const StoragePage(),
title: "Flutter Demo",
theme: ThemeData(
primarySwatch: Colors.blue,
),
),
);
}
}
ストレージオブジェクトの作成
まず、ファイル1つにつき1つのStorage
オブジェクトを作成します。
作成時にリモート側の相対パスを記述したStorageQuery
を渡します。
StorageオブジェクトはChangeNotifier
を継承しているので、addListener
やriverpodのChangeNotifierProvider
などを合わせて利用し状態を監視することができます。
final storage = Storage(const StorageQuery("test/file"));
class StoragePage extends StatefulWidget {
const StoragePage({super.key});
@override
State<StatefulWidget> createState() => StoragePageState();
}
class StoragePageState extends State<StoragePage> {
final storage = Storage(const StorageQuery("test/file"));
final controller = TextEditingController();
@override
void initState() {
super.initState();
storage.addListener(_handledOnUpdate);
}
void _handledOnUpdate() {
setState(() {});
}
@override
void dispose() {
super.dispose();
storage.removeListener(_handledOnUpdate);
storage.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("App Demo")),
body: TextField(
controller: controller,
expands: true,
textAlignVertical: TextAlignVertical.top,
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final text = controller.text;
final bytes = Uint8List.fromList(text.codeUnits);
await storage.uploadWithBytes(bytes);
},
child: const Icon(Icons.upload_file),
),
);
}
}
アップロード
アップロードを行うには下記のメソッドが利用可能です。
-
upload
:ローカルにあるファイルパスを指定してアップロード。 -
uploadWithBytes
:バイトデータを渡して直接アップロード。
戻り値にStorageValue
が渡されます。ここにアップロードしたファイルのリモートのフルパスが格納されています。
final bytes = Uint8List.fromList(text.codeUnits);
final storageValue = await storage.uploadWithBytes(bytes);
print("Remote path is: ${storageValue.remote.path}");
ダウンロード
すでにストレージにアップロードされているファイルをダウンロードするにはdownload
のメソッドを利用します。
引数にローカルに保存するファイルの相対パスを指定することも可能です。
戻り値にStorageValue
が渡され、ここにダウンロードしたファイルのローカルのフルパスやファイルの実データが格納されています。
ローカルファイルへの保存はWebでは対応していません。
final bytes = Uint8List.fromList(text.codeUnits);
final storageValue = await storage.download("file.jpg");
print("Local path is: ${storageValue.local.path}");
print("Local data is: ${storageValue.local.bytes}");
StorageAdapter
StorageAdapterScope
を定義する際に渡すことでストレージのシステムを変更することが可能です。
-
RuntimeStorageAdapter
:アプリのメモリ上のみにデータがアップロードされます。実際には保存されません。テスト時に利用してください。 -
LocalStorageAdapter
:端末のローカルにファイルを保存するためのストレージアダプター。downloadやuploadにおけるローカル
とリモート
はどちらも端末内にあることに注意してください。画面モックを実装する際に便利です。Webでは利用できません。 -
FirebaseStorageAdapter
:Cloud Storage for Firebaseを利用するストレージアダプター。アプリ間で利用可能です。Firebaseの初期設定が必要です。
おわりに
自分で使う用途で作ったものですが実装の思想的に合ってそうならぜひぜひ使ってみてください!
また、こちらにソースを公開しているのでissueやPullRequestをお待ちしてます!
また仕事の依頼等ございましたら、私のTwitterやWebサイトで直接ご連絡をお願いいたします!
GitHub Sponsors
スポンサーを随時募集してます。ご支援お待ちしております!