Busabase
Busabase is an open-source (MIT) database and workspace for AI agents — data, docs, skills, and apps in one place. Run it locally, self-host it inside your network, or use Busabase Cloud, and turn age
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Official Flutter SDK for Unilitix — African-first mobile UX analytics
翻訳待ち
Loading the full README.
Read the full README ↗Version: 3.0.0 · pub.dev · GitHub
Unilitix is a mobile analytics SDK built for African markets. It captures session replays, screen flows, custom events, and user identity — with offline-first data delivery and Africa-specific context (network type, carrier, power outage correlation).
3.0.0 is a thin wrapper over the native Unilitix SDKs (Android
com.unilitix:unilitix-android, iOS UnilitixCore), the way Sentry and Datadog
ship Flutter: sessions, identity, consent, the offline queue, uploads and
retries, device and network context, native crashes, ANRs and app hangs run
in the native SDK, so a Flutter app behaves exactly like a native one. The
Dart side keeps what only Dart can see — Dart/Flutter errors, route names,
and masked replay of the widget tree. Upgrading from 2.x? Read
MIGRATION.md.
| Platform | Minimum | Recommended |
|---|---|---|
| Flutter | 3.10+ | 3.22+ |
| Dart | 3.0+ | — |
| Android | API 21+ | API 26+ (screenshots in session replay) |
| iOS | 13.0+ | — |
| Web, desktop | not supported since 3.0.0 (the SDK does nothing there) | — |
| unilitix (Flutter) | Android SDK (Maven Central) | iOS (UnilitixCore, vendored in the pod) |
|---|---|---|
| 3.0.0 | com.unilitix:unilitix-android:1.11.2 | 0.8.0 |
The Android SDK comes from Maven Central through Gradle; nothing to add if
your project already lists mavenCentral() (Flutter's template does).
flutter pub add unilitix
Or add manually to pubspec.yaml:
dependencies:
unilitix: ^3.0.0
Then run:
flutter pub get
In your main.dart, initialize Unilitix before running your app:
import 'package:unilitix/unilitix_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Unilitix.init('YOUR_API_KEY');
Unilitix.runApp(MyApp());
}
Get your API key from Dashboard → Settings → Apps.
Add Unilitix.observer to navigatorObservers and wrap your app content with UnilitixWidget inside the builder:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorObservers: [Unilitix.observer],
builder: (context, child) => UnilitixWidget(child: child!),
);
}
}
⚠️ Always use the
builderpattern. Do not wrapMaterialAppitself withUnilitixWidget— this causes blank frames in session replay.
Run your app in debug mode. Within 5 seconds you should see:
[Unilitix] SDK initialized ✅ v3.0.0 (native session abc123…, consent granted)
[Unilitix] Screen → /home
If you see Observer ⚠️ not connected, ensure Unilitix.observer is in navigatorObservers. The warning clears automatically on first navigation.
Screen tracking is automatic when Unilitix.observer is added. No additional code needed for standard MaterialApp routing.
GoRouter(
observers: [Unilitix.observer],
routes: [...],
)
For screen names to appear correctly in the dashboard, all routes must have a name:
Navigator.push(context, MaterialPageRoute(
settings: RouteSettings(name: '/payment'),
builder: (context) => PaymentScreen(),
));
Without a name, routes appear as MaterialPageRoute<dynamic> in your analytics.
Associate sessions with a user ID after login. Call identify() in two places:
// 1. After successful login
await AuthService.login(email, password);
Unilitix.identify(
user.id,
{
"email": user.email,
"name": user.name,
"phone": user.phoneNumber,
"account_type": user.accountType,
},
);
// 2. On app startup — if already logged in
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Unilitix.init('YOUR_API_KEY');
final user = await AuthService.getCurrentUser();
if (user != null) {
Unilitix.identify(user.id, {"name": user.name, "email": user.email});
}
Unilitix.runApp(MyApp());
}
⚠️ Calling
identify()only on login means returning users who skip login will appear as anonymous.
Unilitix.track("loan_applied", {
"amount": 50000,
"loan_type": "personal",
"currency": "NGN",
});
Event names should be snake_case. Property values can be String, int, double, or bool.
Events go to the native SDK's on-device queue and are uploaded in batches
(every flushIntervalSeconds, default 30 s, or as soon as flushBatchSize
events are waiting). Call Unilitix.flush() when an event must leave the
device now — for example right before the user signs out.
Calls made before init() completes are kept (up to 200, oldest dropped)
and sent in order right after it.
Delivery is the native SDK's and follows the Unilitix SDK contract, the same
on every platform: one request per cycle; no response, 408, 429 and 5xx back
off (exponentially, or as Retry-After says) and keep the data; 401/403
pause uploads until the next launch; 402 keeps the data and pauses for
Retry-After (1 s–1 h) or 15 minutes; other 4xx drop that batch. The queue
holds maxOfflineEvents (1,000) events, oldest dropped first. Errors inside
the SDK are logged, never thrown into your app, and never recorded as
crashes.
Crash reporting is on by default (autoTrackCrashes). The Dart side reports
what only Dart can see; everything native is the native SDK's:
This is the beginning of the README. Read the rest at the original. Read the full README ↗