lync 1.0.0
lync: ^1.0.0 copied to clipboard
Cross-platform attribution tracking SDK for Flutter. Track user interactions, app installs, and conversions across mobile platforms.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:lync/lync.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Lync with your configuration
await LyncClient.initialize(
LyncConfig.development(
apiKey: 'your-api-key-here', // Optional for development
globalProperties: {
'app_version': '1.0.0',
'environment': 'development',
},
),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lync Attribution Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Lync Attribution Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
LyncAttribution? _lastAttribution;
String _statusMessage = 'Ready to track events';
bool _isLoading = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Attribution Status',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text(_statusMessage),
if (_lastAttribution != null) ...[
const SizedBox(height: 8),
Text('Last Attribution: ${_lastAttribution!.description}'),
],
],
),
),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Device Information',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text('User ID: ${LyncClient.instance.userId}'),
Text('Session ID: ${LyncClient.instance.sessionId}'),
Text('Device Fingerprint: ${LyncClient.instance.deviceFingerprint?.substring(0, 16)}...'),
],
),
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _isLoading ? null : _trackClick,
child: _isLoading
? const CircularProgressIndicator()
: const Text('Track Click Event'),
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _isLoading ? null : _trackInstall,
child: const Text('Track Install Event'),
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _isLoading ? null : _trackConversion,
child: const Text('Track Conversion Event'),
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _isLoading ? null : _trackCustomEvent,
child: const Text('Track Custom Event'),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _startNewSession,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
),
child: const Text('Start New Session'),
),
],
),
),
);
}
Future<void> _trackClick() async {
setState(() {
_isLoading = true;
_statusMessage = 'Tracking click event...';
});
try {
final attribution = await LyncClient.instance.trackClick(
linkId: 'example-link-123',
customData: {
'button_name': 'demo_click',
'page': 'home',
'timestamp': DateTime.now().toIso8601String(),
},
);
setState(() {
_lastAttribution = attribution;
_statusMessage = attribution != null
? 'Click tracked with attribution!'
: 'Click tracked (no attribution)';
});
} catch (e) {
setState(() {
_statusMessage = 'Error tracking click: $e';
});
} finally {
setState(() => _isLoading = false);
}
}
Future<void> _trackInstall() async {
setState(() {
_statusMessage = 'Tracking install event...';
});
try {
final attribution = await LyncClient.instance.trackInstall(
referrer: 'https://example.com/campaign',
customData: {
'install_source': 'demo',
'first_launch': true,
},
);
setState(() {
_lastAttribution = attribution;
_statusMessage = attribution != null
? 'Install tracked with attribution!'
: 'Install tracked (no attribution)';
});
} catch (e) {
setState(() {
_statusMessage = 'Error tracking install: $e';
});
}
}
Future<void> _trackConversion() async {
setState(() {
_statusMessage = 'Tracking conversion event...';
});
try {
final attribution = await LyncClient.instance.trackConversion(
conversionType: 'purchase',
value: 29.99,
currency: 'USD',
customData: {
'product_id': 'demo-product',
'category': 'premium',
},
);
setState(() {
_lastAttribution = attribution;
_statusMessage = attribution != null
? 'Conversion tracked with attribution!'
: 'Conversion tracked (no attribution)';
});
} catch (e) {
setState(() {
_statusMessage = 'Error tracking conversion: $e';
});
}
}
Future<void> _trackCustomEvent() async {
setState(() {
_statusMessage = 'Tracking custom event...';
});
try {
final attribution = await LyncClient.instance.trackEvent(
eventType: 'feature_used',
eventData: {
'feature_name': 'demo_feature',
'usage_count': 1,
},
customData: {
'user_type': 'demo',
},
);
setState(() {
_lastAttribution = attribution;
_statusMessage = attribution != null
? 'Custom event tracked with attribution!'
: 'Custom event tracked (no attribution)';
});
} catch (e) {
setState(() {
_statusMessage = 'Error tracking custom event: $e';
});
}
}
Future<void> _startNewSession() async {
await LyncClient.instance.startNewSession();
setState(() {
_statusMessage = 'New session started!';
_lastAttribution = null;
});
}
}