flutter_piwikpro 2.0.0
flutter_piwikpro: ^2.0.0 copied to clipboard
A dedicated Piwik PRO SDK that brings Piwik PRO Analytics to Flutter-based applications.
example/lib/main.dart
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:flutter_piwikpro/model/ecommerce_transaction_item.dart';
import 'package:flutter_piwikpro/model/ecommerce_product.dart';
import 'package:flutter_piwikpro/flutter_piwikpro.dart';
import 'package:flutter_piwikpro/model/session_hash.dart';
void main() {
final _ecommerceTransactionItems = [
EcommerceTransactionItem(category: 'cat1', sku: 'sku1', name: 'name1', price: 20, quantity: 1),
EcommerceTransactionItem(category: 'cat2', sku: 'sku2', name: 'name2', price: 10, quantity: 1),
EcommerceTransactionItem(category: 'cat3', sku: 'sku3', name: 'name3', price: 30, quantity: 2),
];
final _ecommerceProducts = [
EcommerceProduct(sku: 'craft-311',
name: 'Unicorn Iron on Patch',
category: ['Crafts & Sewing', 'Toys'],
price: '49.9089',
quantity: 3,
brand: 'DMZ',
variant: 'blue',
customDimensions: {1: '/Users/Library/Developer/', 2: '20%'}),
EcommerceProduct(sku: 'dert-456')
];
//Replace with your Tracking Server's values
const String _siteId = '01234567-89ab-cdef-0123-456789abcdef';
const String _baseUrl = 'https://your.piwik.pro.server.com';
final _flutterPiwik = FlutterPiwikPro.sharedInstance;
runApp(MyApp(
ecommerceTransactionItems: _ecommerceTransactionItems,
ecommerceProducts: _ecommerceProducts,
siteId: _siteId,
baseUrl: _baseUrl,
flutterPiwik: _flutterPiwik,
));
}
class MyApp extends StatelessWidget {
const MyApp(
{required this.ecommerceTransactionItems,
required this.ecommerceProducts,
required this.siteId,
required this.baseUrl,
required this.flutterPiwik,
Key? key})
: super(key: key);
final List<EcommerceTransactionItem> ecommerceTransactionItems;
final List<EcommerceProduct> ecommerceProducts;
final String siteId;
final String baseUrl;
final FlutterPiwikPro flutterPiwik;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter PiwikPro SDK Demo'),
bottom: const TabBar(
tabs: [
Tab(text: 'Basic'),
Tab(text: 'Ecommerce'),
Tab(text: 'User'),
Tab(text: 'Settings'),
],
isScrollable: true,
),
),
body: TabBarView(
children: [
_buildBasicTab(),
_buildEcommerceTab(),
_buildUserTab(),
_buildSettingsTab(),
],
),
),
),
);
}
Widget _buildBasicTab() {
return _buildScrollableColumn([
_buildSectionHeader('Configuration'),
_buildButton('Configure Tracker', () async {
try {
final result = await flutterPiwik.configureTracker(baseURL: baseUrl, siteId: siteId);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildSectionHeader('Screen Tracking'),
_buildButton('Track Screen', () async {
try {
final result = await flutterPiwik.trackScreen(screenName: "test", title: "test title");
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildSectionHeader('Event Tracking'),
_buildButton('Track Custom Event', () async {
try {
final result = await flutterPiwik.trackCustomEvent(
action: 'test action',
category: 'test category',
name: 'test name',
path: 'test path',
value: 120);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Track Exception', () async {
try {
final result = await flutterPiwik.trackException(
description: "description of an exception");
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Track Social Interaction', () async {
final result = await flutterPiwik.trackSocialInteraction(
network: "facebook",
interaction: "like"
);
print(result);
_showSnackBar(result);
}),
_buildButton('Track Goal', () async {
final result = await flutterPiwik.trackGoal(
goal: "27ecc5e3-8ae0-40c3-964b-5bd8ee3da059",
revenue: 2.0,
currencyCode: "USD"
);
print(result);
_showSnackBar(result);
}),
_buildSectionHeader('Link Tracking'),
_buildButton('Track Download', () async {
try {
final result = await flutterPiwik.trackDownload('http://your.server.com/bonusmap2.zip');
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Track Outlink', () async {
final result = await flutterPiwik.trackOutlink(
"piwikPRO://piwikpro.com"
);
print(result);
_showSnackBar(result);
}),
_buildButton('Track Campaign', () async {
final result = await flutterPiwik.trackCampaign(
"http://www.example.com?utm_campaign=camp_name3&pk_source=source&pk_medium=medium&pk_keyword=keyword&pk_content=content&pk_cid=id_code"
);
print(result);
_showSnackBar(result);
}),
_buildSectionHeader('Application Events'),
_buildButton('Track Application Install', () async {
try {
final result = await flutterPiwik.trackApplicationInstall();
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Track Application Update', () async {
try {
final result = await flutterPiwik.trackApplicationUpdate();
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
]);
}
Widget _buildEcommerceTab() {
return _buildScrollableColumn([
_buildSectionHeader('Transactions'),
_buildButton('Track Ecommerce Transaction', () async {
final result = await flutterPiwik.trackEcommerceTransaction(
identifier: "testId",
grandTotal: 100,
subTotal: 10,
tax: 5,
shippingCost: 100,
discount: 6,
transactionItems: ecommerceTransactionItems,
);
print(result);
_showSnackBar(result);
}),
_buildSectionHeader('Products'),
_buildButton('Track Ecommerce Product Detail View', () async {
final result = await flutterPiwik.trackEcommerceProductDetailView(
products: ecommerceProducts,
currencyCode: 'USD',
);
print(result);
_showSnackBar(result);
}),
_buildSectionHeader('Cart'),
_buildButton('Track Ecommerce Cart Update', () async {
final result = await flutterPiwik.trackEcommerceCartUpdate(
grandTotal: '6000.43',
products: ecommerceProducts,
currencyCode: 'USD',
);
print(result);
_showSnackBar(result);
}),
_buildButton('Track Ecommerce Add to Cart', () async {
final result = await flutterPiwik.trackEcommerceAddToCart(
products: ecommerceProducts,
currencyCode: 'USD',
);
print(result);
_showSnackBar(result);
}),
_buildButton('Track Ecommerce Remove from Cart', () async {
final result = await flutterPiwik.trackEcommerceRemoveFromCart(
products: ecommerceProducts,
currencyCode: 'USD',
);
print(result);
_showSnackBar(result);
}),
_buildButton('Track Ecommerce Order', () async {
final result = await flutterPiwik.trackEcommerceOrder(
identifier: 'order-3415',
grandTotal: '10000',
subTotal: '120.00',
tax: '39.60',
shippingCost: '60.00',
discount: '18.00',
products: ecommerceProducts,
currencyCode: 'USD',
);
print(result);
_showSnackBar(result);
}),
]);
}
Widget _buildUserTab() {
return _buildScrollableColumn([
_buildSectionHeader('User Identification'),
_buildButton('Set User ID', () async {
try {
final result = await flutterPiwik.setUserId('user-12345');
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Set User Email', () async {
try {
final result = await flutterPiwik.setUserEmail('user@example.com');
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Set Visitor ID', () async {
try {
final result = await flutterPiwik.setVisitorId('visitor-67890');
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Set Visitor ID from Deep Link', () async {
try {
const deepLinkUrl = 'https://example.com?pk_vid=41c90f410ed00000';
final result = await flutterPiwik.setVisitorIdFromDeepLink(deepLinkUrl);
print('Set Visitor ID from Deep Link result: $result');
_showSnackBar('Set Visitor ID from Deep Link result: $result');
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildSectionHeader('Visitor ID Lifetime'),
_buildVisitorIDLifetimeConfig(),
_buildVisitorIDLifetimeDisplay(),
]);
}
Widget _buildVisitorIDLifetimeConfig() {
final TextEditingController controller = TextEditingController(text: '3600');
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: TextField(
controller: controller,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Visitor ID Lifetime (seconds)',
border: OutlineInputBorder(),
helperText: 'Enter the lifetime in seconds (e.g., 3600 for 1 hour)',
),
),
),
ElevatedButton(
onPressed: () async {
try {
final int seconds = int.parse(controller.text);
final int milliseconds = seconds * 1000;
final result = await flutterPiwik.setVisitorIDLifetime(milliseconds);
print(result);
_showSnackBar(result);
final currentLifetime = await flutterPiwik.getVisitorIDLifetime();
print('Current visitor ID lifetime: $currentLifetime milliseconds (${currentLifetime / 1000} seconds)');
_showSnackBar('Current visitor ID lifetime: $currentLifetime milliseconds (${currentLifetime / 1000} seconds)');
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12.0),
),
child: const Text('Set Visitor ID Lifetime'),
),
],
);
}
Widget _buildVisitorIDLifetimeDisplay() {
return VisitorIDLifetimeDisplay(flutterPiwik: flutterPiwik);
}
Widget _buildSettingsTab() {
return _buildScrollableColumn([
_buildSectionHeader('Session Settings'),
_buildButton('Set Session Timeout', () async {
try {
// Set session timeout to 30 minutes (1800000 milliseconds)
final result = await flutterPiwik.setSessionTimeout(1800000);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Set Dispatch Interval', () async {
try {
// Set dispatch interval to 5 minutes (300000 milliseconds)
final result = await flutterPiwik.setDispatchInterval(300000);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Dispatch Events', () async {
try {
final result = await flutterPiwik.dispatch();
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildSectionHeader('Session Hash'),
_buildSessionHashDisplay(),
_buildSectionHeader('Device Information'),
_buildButton('Get User Agent', () async {
try {
final userAgent = await flutterPiwik.getUserAgent();
print('User Agent: $userAgent');
_showSnackBar('User Agent: $userAgent');
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildSectionHeader('Privacy Settings'),
_buildButton('Set Anonymization State', () async {
final result = await flutterPiwik.setAnonymizationState(true);
print(result);
_showSnackBar(result);
}),
_buildButton('Set Include Default Variables', () async {
try {
final result = await flutterPiwik.setIncludeDefaultVariables(true);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Opt Out', () async {
try {
final result = await flutterPiwik.optOut(true);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
_buildButton('Dry Run', () async {
try {
final result = await flutterPiwik.dryRun(true);
print(result);
_showSnackBar(result);
} catch (exception) {
print(exception);
_showSnackBar('Error: $exception');
}
}),
]);
}
Widget _buildSessionHashDisplay() {
return SessionHashDisplay(flutterPiwik: flutterPiwik);
}
Widget _buildScrollableColumn(List<Widget> children) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
),
);
}
Widget _buildSectionHeader(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
Widget _buildButton(String title, VoidCallback onPressed) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12.0),
),
child: Text(title),
),
);
}
void _showSnackBar(String message) {
print('Snackbar: $message');
}
}
class VisitorIDLifetimeDisplay extends StatefulWidget {
final FlutterPiwikPro flutterPiwik;
const VisitorIDLifetimeDisplay({
Key? key,
required this.flutterPiwik,
}) : super(key: key);
@override
State<VisitorIDLifetimeDisplay> createState() => _VisitorIDLifetimeDisplayState();
}
class _VisitorIDLifetimeDisplayState extends State<VisitorIDLifetimeDisplay> {
int? _lifetimeValue;
String _status = 'Not loaded';
Future<void> _getVisitorIDLifetime() async {
try {
setState(() {
_status = 'Loading...';
});
final result = await widget.flutterPiwik.getVisitorIDLifetime();
setState(() {
_lifetimeValue = result;
_status = 'Loaded';
});
print('Current visitor ID lifetime: $result milliseconds (${result / 1000} seconds)');
} catch (exception) {
setState(() {
_status = 'Error: $exception';
});
print(exception);
}
}
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(vertical: 16.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Current Visitor ID Lifetime',
style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 16.0),
if (_lifetimeValue != null) ...[
Text(
'$_lifetimeValue milliseconds',
style: Theme.of(context).textTheme.headlineMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: 8.0),
Text(
'${_lifetimeValue! / 1000} seconds',
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
] else ...[
Text(
_status,
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
],
const SizedBox(height: 16.0),
ElevatedButton(
onPressed: _getVisitorIDLifetime,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12.0),
),
child: const Text('Get Visitor ID Lifetime'),
),
],
),
),
);
}
}
class SessionHashDisplay extends StatefulWidget {
final FlutterPiwikPro flutterPiwik;
const SessionHashDisplay({
Key? key,
required this.flutterPiwik,
}) : super(key: key);
@override
State<SessionHashDisplay> createState() => _SessionHashDisplayState();
}
class _SessionHashDisplayState extends State<SessionHashDisplay> {
SessionHash? _sessionHash;
String _status = 'Not loaded';
Future<void> _getSessionHash() async {
try {
setState(() {
_status = 'Loading...';
});
final result = await widget.flutterPiwik.getSessionHash();
setState(() {
_sessionHash = result;
_status = 'Loaded';
});
print('Current session hash: $result');
} catch (exception) {
setState(() {
_status = 'Error: $exception';
});
print(exception);
}
}
@override
void initState() {
super.initState();
_getSessionHash();
}
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(vertical: 16.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Current Session Hash State',
style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 16.0),
if (_sessionHash != null) ...[
Text(
_sessionHash.toString().split('.').last,
style: Theme.of(context).textTheme.headlineMedium,
textAlign: TextAlign.center,
),
const SizedBox(height: 8.0),
Text(
_getSessionHashDescription(_sessionHash!),
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
] else ...[
Text(
_status,
style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center,
),
],
const SizedBox(height: 16.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () async {
try {
await widget.flutterPiwik.setSessionHash(SessionHash.disabled);
_getSessionHash();
} catch (e) {
print('Error setting session hash: $e');
}
},
child: const Text('Disable'),
),
ElevatedButton(
onPressed: () async {
try {
await widget.flutterPiwik.setSessionHash(SessionHash.enabled);
_getSessionHash();
} catch (e) {
print('Error setting session hash: $e');
}
},
child: const Text('Enable'),
),
ElevatedButton(
onPressed: () async {
try {
await widget.flutterPiwik.setSessionHash(SessionHash.notSet);
_getSessionHash();
} catch (e) {
print('Error setting session hash: $e');
}
},
child: const Text('Not Set'),
),
],
),
const SizedBox(height: 8.0),
ElevatedButton(
onPressed: _getSessionHash,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12.0),
),
child: const Text('Refresh Session Hash'),
),
],
),
),
);
}
String _getSessionHashDescription(SessionHash hash) {
switch (hash) {
case SessionHash.disabled:
return 'Session hash is disabled';
case SessionHash.enabled:
return 'Session hash is enabled';
case SessionHash.notSet:
return 'Session hash is not set (using default)';
}
}
}