こんにちは!
最近、Flutterについて学習をしているため、知識を定着させるためにも調べたことを記事としてアウトプットしていきたいと思います。
今回は、プライベートで行なっているチーム開発で使用されているライブラリについて使い方や代替ライブラリなどを調べてきたので、紹介したいと思います。
1. provider 状態管理
Flutterアプリの「状態(State)」、を管理するためのライブラリです。
特徴
Googleが推奨しており、Flutterに標準で用意されているInheritedWidgetをより使いやすくしたものです。
シンプルで学習コストが低く、小〜中規模のアプリケーションに最適です。
ChangeNotifierと組み合わせることで、状態の変更をUIに効率的に通知できます。
使用例
アプリの最上位でMultiProviderを使い、AuthProvider(認証状態)やDiaryProvider(日記データ)をアプリ全体で利用できるように設定しています。
void main() async {
// ...
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AuthProvider()),
ChangeNotifierProvider(create: (_) => DiaryProvider()),
],
child: const MyApp(),
),
);
}
UI側では、Provider.of(context)やConsumerウィジェットを使って、状態にアクセスしたり、状態の変更に応じてUIを自動で更新したりします。
class ProfileContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<AuthProvider>( // Consumerを使ってAuthProviderの状態を監視
builder: (context, authProvider, child) {
final user = authProvider.user; // ユーザー情報を取得
return Container(
child: Text(user?.name ?? 'ゲストユーザー'), // ユーザー名を表示
);
},
);
}
}
代替ライブラリ
providerの他にも以下のようなライブラリがありました。特にRiverpodは解説記事も多かったので、これからFlutterで開発される方はiverpodを使ってみる方がいいかもしれません。
- Riverpod
- providerの作者が開発した後継ライブラリ。より安全でテストしやすく、大規模開発にも向いている
- Bloc
- ユーザー操作などのイベントを元にビジネスロジックを処理し、その結果としてUIの状態を一方向に更新することで、テストしやすく見通しの良いアプリ開発を可能にするライブラリ
- GetX
- 状態管理、ルーティング、依存性注入などを一つのパッケージで提供する軽量フレームワーク
2. http apiクライアント
APIサーバーからデータを取得したり、サーバーにデータを送信したりするための、HTTP通信を行う基本的なライブラリです。
特徴
シンプルで分かりやすいAPIを提供しており、GET, POST, PUT, DELETEなどの基本的なHTTPリクエストを簡単に行えます。
Dartの標準ライブラリのような位置づけで、多くのプロジェクトで採用されています。
使用例
以下のように記述することでデータを取得(GET)したり、作成(POST)したりできます。
import 'package:http/http.dart' as http;
class DiaryApiService extends BaseApiService {
Future<List<Diary>> getDiaries() async {
final response = await http.get(
Uri.parse('${BaseApiService.baseUrl}/diaries'),
headers: await getHeaders(),
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return (data['diaries'] as List)
.map((diary) => Diary.fromJson(diary))
.toList();
} else {
throw Exception('日記の取得に失敗しました。');
}
}
}
代替ライブラリ
- Dio
- httpよりも高機能なHTTPクライアント。リクエストのキャンセル、インターセプター(、タイムアウト設定などが簡単に行える
- Chopper
- コード生成を利用して、APIの定義からクライアントコードを自動で作成できるライブラリ。型安全なAPIアクセスを実現できる
3. shared_preferences データの永続化
アプリを閉じても消えない簡単なデータ(設定情報、認証トークンなど)を、キーと値のペアでデバイス内に保存するためのライブラリです。
特徴
文字列、数値、真偽値などのプリミティブなデータ型を簡単に保存・読み込みできます。
内部的にはiOSではNSUserDefaults、AndroidではSharedPreferencesを利用しています。
使用例
BaseApiServiceで、ログイン時に受け取った認証トークンをデバイスに保存し、APIリクエストの際にヘッダーに付与するために使用しています。
import 'package:shared_preferences/shared_preferences.dart';
class BaseApiService {
static const String tokenKey = 'auth_token';
// トークンを保存する
Future<void> saveToken(String token) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(tokenKey, token);
}
// トークンを取得する
Future<String?> getToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(tokenKey);
}
}
代替ライブラリ
- Hive
- Dartで書かれた高速なKey-Valueデータベース。shared_preferencesよりも高速で、オブジェクトをそのまま保存することも可能
- flutter_secure_storage
- トークンなどの機密情報を、iOSのKeychainやAndroidのKeystoreといったセキュアな領域に保存するためのライブラリ
4. intl 多言語対応
日付、数値、通貨などをユーザーの言語や地域に合わせて適切にフォーマット(国際化対応)するためのライブラリです。
特徴
DateFormatクラスを使うことで、様々な形式で日付や時刻を整形できます。
多言語対応(ローカライゼーション)の基盤としても利用されます。
使用例
現在の日付をyyyy-MM-ddという形式で表示するためにDateFormatを使っています。
// screens/pedometer/pedometer_screen.dart
import 'package:intl/intl.dart';
class _PedometerScreenState extends State<PedometerScreen> {
String _formatDate(DateTime date) {
return DateFormat('yyyy-MM-dd').format(date);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
Text(
'Date: ${_formatDate(DateTime.now())}', // 整形した日付を表示
),
],
),
),
);
}
}
5. pedometer 歩数計
スマートフォンのハードウェアセンサーにアクセスし、歩数データを取得するためのライブラリです。
特徴
歩数の変化をStreamとして受け取ることができるため、リアルタイムで歩数を画面に反映させることが可能です。
バックグラウンドでの歩数計測にも対応しています。
使用例
歩数が更新されるたびに画面の表示を更新する処理で使用しています。
import 'package:pedometer/pedometer.dart';
class _PedometerScreenState extends State<PedometerScreen> {
Stream<StepCount>? _stepCountStream;
int _steps = 0;
void _initPedometer() {
_stepCountStream = Pedometer.stepCountStream;
_stepCountStream!.listen((StepCount event) { // 歩数ストリームを監視
setState(() {
_steps = event.steps; // 歩数を更新
});
}).onError((error) {
// エラー処理
});
}
}
6. geolocator 位置情報の取得
デバイスのGPS機能を利用して、現在の緯度・経度などの位置情報を取得するためのライブラリです。
特徴
現在の位置を一度だけ取得したり、位置情報の変化をストリームで継続的に受け取ったりすることができます。
位置情報サービスが有効か、アプリに権限が付与されているかなどを簡単にチェックできます。
使用例
画面の初期化時にユーザーの現在位置を取得するために使用しています。
import 'package:geolocator/geolocator.dart';
class _MapScreenState extends State<MapScreen> {
Position? _currentPosition;
Future<void> _getCurrentLocation() async {
try {
// 位置情報サービスが有効かチェック
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled)
// 権限をチェック・リクエスト
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
// 現在位置を取得
Position position = await Geolocator.getCurrentPosition();
setState(() {
_currentPosition = position;
});
} catch (e) {
// エラー処理
}
}
}
7. permission_handler 権限管理
位置情報、カメラ、通知、マイクなど、OSが保護している機能へのアクセス許可をユーザーに求めるためのライブラリです。
特徴
様々な種類の権限に対応しており、統一されたインターフェースで権限の状態確認やリクエストを行えます。
ユーザーが権限を「永続的に拒否」した場合も検知できるため、設定画面へ誘導するなどの適切な対応が可能です。
使用例
ユーザーのアプリ起動時に、位置情報と通知の権限をリクエストする処理で使用しています。
import 'package:permission_handler/permission_handler.dart';
class PermissionService {
Future<void> requestPermissions() async {
await _requestLocationPermission();
await _requestNotificationPermission();
}
Future<void> _requestLocationPermission() async {
final status = await Permission.location.request();
if (status.isGranted) {
print("Location permission granted");
} else if (status.isPermanentlyDenied) {
openAppSettings(); // 設定画面を開く
}
}
}
8. url_launcher 部リンクを開く
アプリ内からブラウザでWebサイトを開いたり、電話をかけたり、メールアプリを起動したりするためのライブラリです
特徴
URL文字列を渡すだけで、プラットフォームに応じた適切な処理(ブラウザ起動など)を自動で行ってくれます。
tel:やmailto:といったスキーマにも対応しています。
使用例
ウィジェット内のボタンが押された際に、外部サイトを開くために使用しています
import 'package:url_launcher/url_launcher.dart';
class UrlLauncherHelper {
static Future<void> openUrl(String url) async {
final Uri uri = Uri.parse(url);
if (!await launchUrl(uri)) {
throw Exception('Could not launch $url');
}
}
}
class TravelAdvisorySection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton.icon(
onPressed: () {
// 定義したURLをヘルパーに渡して実行
UrlLauncherHelper.openUrl(AppConstants.mofaTravelAdvisoryUrl);
},
icon: const Icon(Icons.open_in_new),
label: const Text('外部サイト'),
);
}
}
まとめ
今回はチーム開発で使用しているFlutterのライブラリを紹介してみました。
紹介したもの以外にも便利なライブラリはたくさんあると思うので、ぜひおすすめのライブラリがありましたらコメントで教えていただけると幸いです。
最後までご覧いただきありがとうございました。