Flutter SDK
The Snapbug Flutter SDK provides a Dart bridge to the native Snapbug SDK, enabling network inspection, analytics monitoring, crash reporting, and live logs from your Flutter app on Android and iOS.
Requirements
- Flutter >= 3.3.0
- Dart >= 3.5.4
- Dio >= 5.0.0 (for automatic network interception)
- Android
minSdk23 - iOS: Apple-silicon simulators or physical devices (the bundled XCFramework excludes
x86_64simulator slices)
Installation
Add the dependency to your pubspec.yaml:
dependencies:
snapbug_flutter: ^0.1.0Then run:
flutter pub getThe plugin bundles the native Snapbug SDK on both platforms — no extra Gradle or CocoaPods dependencies are needed (on iOS, run pod install as usual after adding the plugin).
Quick Start
The Flutter plugin is a bridge: the host app starts the native SDK, then the Dart side connects to it.
1. Start the native SDK
Android — in your Application class:
import io.snapbug.sdk.SnapbugContext
import io.snapbug.sdk.startSnapbug
import io.snapbug.sdk.network.core.SnapbugNetwork
import io.snapbug.sdk.plugins.analytics.SnapbugAnalytics
import io.snapbug.sdk.plugins.crashreporter.SnapbugCrashReporter
import io.snapbug.sdk.plugins.debugfeedback.SnapbugDebugFeedback
import io.snapbug.sdk.plugins.device.SnapbugDevice
import io.snapbug.sdk.plugins.logs.SnapbugLogs
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
startSnapbug(SnapbugContext(this)) {
install(SnapbugAnalytics)
install(SnapbugNetwork)
install(SnapbugCrashReporter) { catchFatalErrors = true }
install(SnapbugDevice)
install(SnapbugDebugFeedback)
install(SnapbugLogs)
}
}
}iOS — in your AppDelegate:
import SnapbugSDK
private func startSnapbugSdk() {
SnapbugConfigurationKt.startSnapbug(
context: SnapbugContext(),
block: { config in
config.install(factory: SnapbugAnalytics.shared, configure: { _ in })
config.install(factory: SnapbugNetwork.shared, configure: { _ in })
config.install(factory: SnapbugCrashReporter.shared, configure: { c in
(c as! SnapbugCrashReporterConfig).catchFatalErrors = true
})
config.install(factory: SnapbugDevice.shared, configure: { _ in })
config.install(factory: SnapbugDebugFeedback.shared, configure: { _ in })
config.install(factory: SnapbugLogs.shared, configure: { _ in })
}
)
SnapbugDebugFeedbackIos.shared.start(config: DebugFeedbackConfig(
enabled: true,
screenNameProvider: { "Flutter" },
collectTimeline: true,
timelineMaxEvents: 200,
timelineMaxAgeSeconds: 60,
appVersion: "1.0.0"
))
}Call startSnapbugSdk() in application(_:didFinishLaunchingWithOptions:) before the Flutter engine starts.
2. Start the Dart side
import 'dart:async';
import 'package:snapbug_flutter/snapbug_flutter.dart';
void main() {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
await Snapbug.start();
runApp(const MyApp());
}, (error, stack) {
SnapbugCrashReporter.reportError(error, stack);
}, zoneSpecification: SnapbugLogs.zoneSpecification());
}All Dart plugins are enabled by default; pass plugins: [...] to Snapbug.start() to enable a subset.
Logs
Log lines stream into the Logs inspector in real time:
- Android — the native SDK captures logcat; Dart
print/debugPrintland there under thefluttertag, so nothing extra is needed. - iOS — the Flutter engine routes Dart output to os_log, past stdout, so the Dart
SnapbugLogsplugin forwards it itself:debugPrint(including Flutter framework error dumps with stack traces) is hooked automatically bySnapbug.start(); plainprint()is captured throughSnapbugLogs.zoneSpecification()passed torunZonedGuardedas shown above.
Network Inspection
With Dio
Add the SnapbugDioInterceptor to your Dio client:
import 'package:dio/dio.dart';
import 'package:snapbug_flutter/snapbug_flutter.dart';
final dio = Dio();
dio.interceptors.add(SnapbugDioInterceptor());All HTTP requests made through this Dio instance appear in the network inspector.
Manual Logging
For HTTP clients other than Dio, log requests and responses manually. Generate a call ID first so the request and response are linked:
final network = Snapbug.getPlugin<SnapbugNetwork>()!;
final callId = network.generateCallId();
network.logRequest(
callId: callId,
url: 'https://api.example.com/users',
method: 'GET',
headers: {'Authorization': 'Bearer token'},
);
network.logResponse(
callId: callId,
durationMs: 150,
statusCode: 200,
contentType: 'application/json',
headers: {'content-type': 'application/json'},
body: '{"users": []}',
);Analytics
Log analytics events with a source identifier:
Snapbug.analytics('firebase').logEvents([
AnalyticsEvent('screen_view', properties: {'screen_name': 'Home'}),
AnalyticsEvent('button_click', properties: {'button_id': 'sign_up'}),
]);You can use any string as the source identifier to group events (e.g., firebase, amplitude, mixpanel).
Crash Reporter
Automatic Fatal Error Capture
Enable fatal error capture when starting the SDK, and wrap your entry point in runZonedGuarded:
void main() {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
await Snapbug.start(
plugins: [SnapbugCrashReporter(catchFatalErrors: true)],
);
runApp(const MyApp());
}, (error, stack) {
SnapbugCrashReporter.reportError(error, stack);
});
}Manual Error Reporting
Report caught exceptions manually:
try {
await riskyOperation();
} catch (error, stackTrace) {
SnapbugCrashReporter.reportError(error, stackTrace);
}Architecture
The Flutter SDK follows a bridge architecture:
Flutter (Dart)
|
v
Platform Channel (Method Channel)
|
v
Native Snapbug SDK (Android / iOS)
|
v
WebSocket / WebRTC --> Snapbug inspector
Dart calls are forwarded to the native Snapbug SDK, which owns the connection to the inspector (Chrome Extension room-code flow or local network).
Example App
A complete Flutter example app is available at SnapbugFlutter/example/ in the repository.
To run it:
cd SnapbugFlutter/example
flutter runTo build for a platform explicitly:
flutter build apk --debug # Android
flutter build ios --simulator # iOS (Apple-silicon simulator)Next Steps
- Connect your device
- Troubleshooting for common issues