ℹ️
今のアプリのバージョンを画面に表示したい
Overview
たまに、インストールしたアプリを見てアプリのバージョン1.0.0
って書いてあることありませんか?
Flutterには、現在のアプリのバージョンを表示する便利なパッケージでpackage_info_plus
というものがあります。昔は、package_info
というものだったようですが、こちらに変更になったようです。
iOS、Android両方に対応しており、特別な設定もしないでそのまま使えます。
summary
早速使ってみました。pub getして、Exampleのソースコードをそのまま使用しただけです。
main.dart
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'PackageInfoPlus Demo',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: const Color(0x9f4376f8),
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
PackageInfo _packageInfo = PackageInfo(
appName: 'Unknown',
packageName: 'Unknown',
version: 'Unknown',
buildNumber: 'Unknown',
buildSignature: 'Unknown',
installerStore: 'Unknown',
);
void initState() {
super.initState();
_initPackageInfo();
}
Future<void> _initPackageInfo() async {
final info = await PackageInfo.fromPlatform();
setState(() {
_packageInfo = info;
});
}
Widget _infoTile(String title, String subtitle) {
return ListTile(
title: Text(title),
subtitle: Text(subtitle.isEmpty ? 'Not set' : subtitle),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PackageInfoPlus example'),
elevation: 4,
),
body: ListView(
children: <Widget>[
_infoTile('App name', _packageInfo.appName),
_infoTile('Package name', _packageInfo.packageName),
_infoTile('App version', _packageInfo.version),
_infoTile('Build number', _packageInfo.buildNumber),
_infoTile('Build signature', _packageInfo.buildSignature),
_infoTile(
'Installer store',
_packageInfo.installerStore ?? 'not available',
),
],
),
);
}
}
📱ビルドするとこのように表示されます
iOS
Android
thoughts
PackageInfo
というクラスですが、こちらはどうやら、非同期のメソッドを呼び出して、使っているようで、FutureBuilder
を使えば、initState
を使用しなくてもアプリのバージョンの情報を取得できるようです。
StatelessWidgetでもできる
main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'PackageInfoPlus Demo',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: const Color(0x9f4376f8),
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<String>(
future: _getAppVersion(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text('アプリのバージョン: ${snapshot.data}');
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return const CircularProgressIndicator();
}
},
),
),
);
}
Future<String> _getAppVersion() async {
final packageInfo = await PackageInfo.fromPlatform();
return packageInfo.version;
}
}
flutter_hooksを使ったパターンも考えてみました
useFuture
を使うとFutureBuilder
より短く簡潔に書けます。とはいっても使用例があまりないので、短いコードでも書くのが大変でした💦
タイトル
main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:package_info_plus/package_info_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'PackageInfoPlus Demo',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: const Color(0x9f4376f8),
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends HookWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
// useMemoizedでキャッシュすると、再描画時にキャッシュした値を返す
final memo = useMemoized(() => _getAppVersion(), []);
// useFutureで非同期処理を実行する
final snapshot = useFuture(memo);
return Scaffold(
appBar: AppBar(
title: const Text('PackageInfoPlus Demo Hooks'),
),
// FutureBuilderと同じようにsnapshotを使う
body: snapshot.connectionState == ConnectionState.done
? Center(
child: Text(
'アプリのバージョン: ${snapshot.data.toString()}',
style: const TextStyle(fontSize: 24),
),
)
: const Center(
child: CircularProgressIndicator(),
),
);
}
Future<String> _getAppVersion() async {
final packageInfo = await PackageInfo.fromPlatform();
return packageInfo.version;
}
}
こんな感じになります
最近副業で、アプリのバージョンをUIに表示する要件があったので、こちらのパッケージを今回使ってみました。
Discussion