encore_flutter 1.0.21
encore_flutter: ^1.0.21 copied to clipboard
Flutter plugin wrapping the native Encore iOS and Android SDKs for monetization, offers, and entitlements. All offer UI is rendered natively via StoreKit (iOS) and Play Billing (Android).
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:encore_flutter/encore_flutter.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Encore Flutter Example',
theme: ThemeData(
colorSchemeSeed: Colors.deepPurple,
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final List<String> _eventLog = [];
@override
void initState() {
super.initState();
_initEncore();
}
void _log(String message) {
final now = DateTime.now();
final timestamp = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}';
setState(() => _eventLog.insert(0, '[$timestamp] $message'));
}
Future<void> _initEncore() async {
await Purchases.configure(
PurchasesConfiguration('YOUR_REVENUECAT_API_KEY'),
);
await Encore.shared.configure(
apiKey: 'pk_test_dyzxq1bl6jdt9dly78qdjnad',
logLevel: EncoreLogLevel.debug,
);
Encore.shared.onEncorePurchaseRequest((purchaseRequest) async {
_log('onPurchaseRequest: productId=${purchaseRequest.productId}, placementId=${purchaseRequest.placementId}');
final products = await Purchases.getProducts([purchaseRequest.productId]);
if (products.isNotEmpty) {
await Purchases.purchaseStoreProduct(products.first);
}
});
Encore.shared.onPurchaseComplete((result, productId) {
_log('onPurchaseComplete: $productId (token: ${result.purchaseToken})');
});
Encore.shared.onPassthrough((placementId) {
_log('onPassthrough: $placementId');
});
await Encore.shared.identify(
userId: 'demo_user_flutter_001',
attributes: const EncoreUserAttributes(
email: 'user@example.com',
subscriptionTier: 'premium',
),
);
_log('identify: demo_user_flutter_001');
}
Future<void> _showOffer() async {
_log('placement: presenting...');
final result = await Encore.shared.placement('example_placement').show();
final message = switch (result) {
EncorePresentationResultGranted() => 'placement: granted',
EncorePresentationResultNotGranted(:final reason) => 'placement: not granted ($reason)',
};
_log(message);
}
Future<void> _resetSdk() async {
await Encore.shared.reset();
_log('reset: SUCCESS');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Encore Flutter Example')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: FilledButton(
onPressed: _showOffer,
child: const Text('Show Offer'),
),
),
const SizedBox(width: 12),
Expanded(
child: OutlinedButton(
onPressed: _resetSdk,
child: const Text('Reset SDK'),
),
),
],
),
),
const Divider(height: 1),
Expanded(
child: _eventLog.isEmpty
? const Center(child: Text('No events yet'))
: ListView.builder(
padding: const EdgeInsets.all(12),
itemCount: _eventLog.length,
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Text(
_eventLog[index],
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontFamily: 'monospace',
),
),
),
),
),
],
),
);
}
}