appxiom_flutter 1.0.7
appxiom_flutter: ^1.0.7 copied to clipboard
Detect and report bugs in Flutter based mobile apps. Reports issues like memory leaks, crashes, ANR and exceptions. Plugin has low memory and size footprint.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:appxiom_flutter/appxiom_flutter.dart';
import 'package:appxiom_flutter/observe.dart';
import 'package:appxiom_flutter/ax_state.dart';
void main() {
// 1. Initialize the Plugin
WidgetsFlutterBinding.ensureInitialized();
// Replace with your keys from Appxiom dashboard
Ax.init("<android_app_key>", "<android_platform_key>");
// For iOS, add keys to Info.plist and call initIOS
Ax.initIOS();
// 2. Configure Network Monitoring (Optional)
Observe().setUrlPatterns([
'/users/{id}', // Groups /users/1, /users/2 etc.
'/posts/{id}'
]);
Observe().setMaskedHeaders([
'Authorization', // Mask sensitive headers
'X-API-KEY'
]);
// 3. Set Custom Identity (Optional)
Ax.setCustomId("<user_id_or_device_id>");
// 4. Start the App using AxApp.run for automatic tracking
AxApp.run(
child: const MyApp(),
screenName: 'MainApp',
widgetName: 'MyApp',
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Appxiom Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const DemoHomeScreen(),
);
}
}
// 5. Connecting StatefulWidgets to Appxiom
// Use AxInitialState for your first screen/splash screen
class DemoHomeScreen extends StatefulWidget {
const DemoHomeScreen({super.key});
@override
State<DemoHomeScreen> createState() => _DemoHomeScreenState();
}
class _DemoHomeScreenState extends AxInitialState<DemoHomeScreen> {
// Set a unique name for meaningful reports in release builds
@override
String get stateClassName => "DemoHomeScreen";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Appxiom Features Demo')),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildSection("General Features", [
_buildButton("Test Issue (Ax.test)", () => Ax.test()),
_buildButton("Custom Issue Report", _reportCustomIssue),
_buildButton("Custom Error Report", _reportCustomError),
_buildButton("Set Activity Marker",
() => Ax.setActivityMarkerAt("Main", "Button Clicked")),
]),
_buildSection("User Journeys (GFI)", [
_buildButton("Start & Complete Goal", _demonstrateGoalTracking),
]),
_buildSection("Network Tracking", [
_buildButton("AxHttp GET Request", _makeApiCall),
_buildButton("AxClient Request", _makeClientCall),
]),
_buildSection("Advanced Tracking", [
_buildButton("Track Isolate crash", _spawnTrackedIsolate),
_buildButton("Set Geo Location",
() => Ax.setCurrentPosition(12.9716, 77.5946)),
]),
],
),
);
}
Widget _buildSection(String title, List<Widget> children) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(title,
style:
const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
),
...children,
const Divider(),
],
);
}
Widget _buildButton(String label, VoidCallback onPressed) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: ElevatedButton(onPressed: onPressed, child: Text(label)),
);
}
// --- Feature Demonstrations ---
void _reportCustomIssue() {
// 6. Custom Issue Reporting
Ax.reportIssue(
"DemoHomeScreen",
"Feature Accessed",
"User clicked the custom issue demonstration button",
);
_showSnackBar("Custom issue reported");
}
void _reportCustomError() {
// 7. Custom Error Reporting
try {
throw Exception("Simulated business logic error");
} catch (e, stack) {
Ax.reportError(e, stack);
_showSnackBar("Caught error reported via Ax.reportError");
}
}
Future<void> _demonstrateGoalTracking() async {
// 8. Goal/User Journey Tracking
_showSnackBar("Starting 'purchase_flow' goal...");
// Begin a goal
int goalId = await Ax.beginGoal("main", "purchase_flow");
// Simulate some process
await Future.delayed(const Duration(seconds: 2));
// Complete the goal
Ax.completeGoal("main", goalId);
_showSnackBar("Goal 'purchase_flow' completed!");
}
Future<void> _makeApiCall() async {
// 9. Regular API call tracking with AxHttp
_showSnackBar("Making AxHttp.get call...");
try {
await AxHttp.get(
Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
_showSnackBar("API call successful (tracked)");
} catch (e) {
_showSnackBar("API call failed: $e");
}
}
Future<void> _makeClientCall() async {
// 10. API tracking using AxClient
_showSnackBar("Making call using AxClient...");
final client = AxHttp.createAxClient();
try {
await client
.get(Uri.parse('https://jsonplaceholder.typicode.com/todos/1'));
_showSnackBar("Client call successful (tracked)");
} finally {
client.close();
}
}
Future<void> _spawnTrackedIsolate() async {
// 11. Isolate Tracking
_showSnackBar("Spawning tracked isolate...");
await AxIsolate.spawn(
name: 'demo_worker_isolate',
entryPoint: _isolateEntryPoint,
message: 'Hello from main!',
);
}
static void _isolateEntryPoint(String message) {
// Any crash here is automatically reported
Future.delayed(const Duration(seconds: 1), () {
throw Exception("Crash inside tracked isolate");
});
}
void _showSnackBar(String message) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message)));
}
}