🔥
FlutterのSubscription管理をラクにするライブラリ「subman」を作った
どうも、mikanecoです。
最近のスマブラはプリンでVIPに行きました。
殴り書きます
サブスク機能があるアプリを作ってると、「この状態、どうやって管理するのが一番スッキリするんだ……」 って何度も思ったので、自分用に作ってたコードをライブラリ化して公開しました!
そもそもsubmanって何?
FlutterアプリでIn-App-Purchase&サブスクリプションを管理するためのユーティリティです!
- 月額/年額/トライアルなど複数プランの状態管理
- レシートが複数ある場合でも「一番有効なやつ」を自動で判定
- 状態の更新をUIやロジックに反映しやすい設計(Riverpodでも組みやすい)
サブスク周りのゴチャゴチャしたif文から卒業できます。
どういうとき便利?
- ユーザーがいろんなプランを購入・切り替えしたときに、どれが今有効か即判断したい
- 有効期限やプラットフォーム(iOS/Android)も一緒に管理したい
- 復元や複数レシート送信時のロジックで悩みたくない
- サーバー検証後の「今どのプランがアクティブ?」を迷いたくない
こんな人には多分刺さります。
使い方ざっくり
- アプリ起動時に初期化
main() で Subman.init() を呼んでサブスク管理を初期化します。
ここで「扱うプロダクトID」や「購入完了時の処理」「エラー時のハンドラ」などもセットできます。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Subman.init(
productIds: ['monthly_subscription', 'yearly_subscription'],
onPurchaseCompleted: (subscription) {
debugPrint('Purchased: ${subscription.productId}');
},
onRestoreCompleted: (subscriptions) {
debugPrint('Restored: $subscriptions');
},
onError: (exception) {
debugPrint('Error: ${exception.code} / ${exception.message}');
},
// 独自のサーバー検証クライアントを使う場合は(ま、ほとんど使うと思うんですけどね)
serverClient: MyServerClient(),
);
runApp(const MyApp());
}
class MyServerClient extends SubscriptionServerClient {
MyServerClient() : super();
Future<bool> verify(Map<String, dynamic> payload) {
// サーバーにレシートを投げて結果を返す
}
}
- サブスクの状態を取得・監視
Subman.activeSubscriptionsStream を購読すれば、
サブスクの変更(購入/復元/解約など)があった時に自動でUIを更新できます。
void initState() {
super.initState();
Subman.activeSubscriptionsStream.listen((subs) {
setState(() {
_status = subs.isEmpty
? 'No active subscription'
: 'Active: ${subs.map((s) => s.productId).join(', ')}';
});
});
}
また、手軽に現在のサブスク状態を取得したい時は、
Subman.isSubscribed や Subman.currentSubscription を使います
final isSubscribed = Subman.isSubscribed;
final current = Subman.currentSubscription;
- 購入・復元処理も一行でOK
UI側で「購入」「復元」ボタンを押したときは、
Subman.purchase(productId) や Subman.restore() を呼ぶかんじ
ElevatedButton(
onPressed: () async {
await Subman.purchase('monthly_subscription');
},
child: const Text('Purchase Monthly'),
),
ElevatedButton(
onPressed: () async {
await Subman.restore();
},
child: const Text('Restore'),
),
これで、サブスクの面倒な状態管理がかなりスッキリします。
ちょっとした特徴
- SubscriptionStateで「今有効なプラン+いろんな情報」がまとまってる
- レシートが複数あってもいい感じに自動判定
- ハンドラで「購入後/復元後」の処理を好きに差し込める
- 必要以上に抽象化しすぎてないので、カスタマイズもしやすい
こういう人向け
- Flutterでサブスク実装してるけどロジックがぐちゃぐちゃになってきた
- Riverpodなどの状態管理と組み合わせて使いたい
- iOS/Android問わず動くアプリの「サブスク有効判定」をシンプルにしたい
注意点とか今後やりたいこと
- もしRiverpodに最適化したProviderパッケージも要望あれば作るかも
- Storeのプラン情報(料金/期間/説明など)をいい感じに扱う仕組みも考え中
最後に
自分のアプリでもガッツリ使ってますが、コードが本当にスッキリしたので、同じ悩みを抱えてる人にはぜひ一度触ってもらいたいです🙏
バグ報告・質問・要望・PRなんでもWelcomeなので、気軽にどうぞ!
以上、サクッとですが紹介でした!
Discussion