seenn_flutter
Flutter SDK for Seenn - Real-time job progress tracking with Live Activity (iOS), and Ongoing Notification (Android) support.
Features
- Real-time Updates - Polling with automatic reconnection
- iOS Live Activity - Lock Screen and Dynamic Island progress
- Android Ongoing Notification - Persistent notification with progress bar
- Provisional Push - iOS 12+ quiet notifications without permission prompt
- ETA Countdown - Smart time estimates with confidence scores
- Parent-Child Jobs - Hierarchical job relationships
- Reactive Streams - RxDart-powered state management
- Error Codes - Standardized error handling with
SeennErrorCode - Input Validation - Client-side validation before native calls
Installation
dependencies:
seenn_flutter: ^0.8.4
Quick Start
import 'package:seenn_flutter/seenn_flutter.dart';
// Initialize
final seenn = Seenn(SeennConfig(
publicKey: 'pk_live_xxx',
baseUrl: 'https://api.seenn.io',
));
// Connect for a user
await seenn.connect(userId: 'user_123');
// Subscribe to a job
final tracker = seenn.jobs.subscribe('job_abc');
tracker.onProgress.listen((update) {
print('Progress: ${update.progress}%');
print('ETA: ${update.etaFormatted}');
});
tracker.onComplete.listen((job) {
print('Job completed!');
});
iOS Live Activity
// Start Live Activity
await seenn.liveActivity.startActivity(
jobId: 'job_abc',
title: 'Processing video...',
);
// Auto-sync with job updates
seenn.jobs.stream('job_abc').listen((job) {
if (job != null) {
seenn.liveActivity.updateActivity(
jobId: job.id,
progress: job.progress,
message: job.message,
);
}
});
iOS Setup
Add to ios/Runner/Info.plist:
<key>NSSupportsLiveActivities</key>
<true/>
Provisional Push (iOS 12+)
Request push notifications without showing a permission prompt:
import 'package:seenn_flutter/seenn_flutter.dart';
// Check current status
final status = await LiveActivity.getPushAuthorizationStatus();
print(status.status); // PushAuthorizationStatus.provisional
print(status.isProvisional); // true if quiet notifications
// Request provisional push (no prompt!)
final granted = await LiveActivity.requestProvisionalPushAuthorization();
if (granted) {
print('Provisional push enabled');
}
// Later: upgrade to full push when ready
if (status.canRequestFullAuthorization) {
await LiveActivity.upgradeToStandardPush(); // Shows prompt
}
Note: Provisional notifications appear silently in Notification Center only. Users can "Keep" or "Turn Off" from their first notification.
Error Handling
All Live Activity operations return results with error codes for programmatic handling:
import 'package:seenn_flutter/seenn_flutter.dart';
print('SDK Version: $sdkVersion'); // '0.8.4'
final result = await LiveActivity.start(
jobId: 'job_123',
title: 'Processing...',
jobType: 'video',
);
if (!result.success) {
switch (result.code) {
case SeennErrorCode.platformNotSupported:
print('Not on iOS');
break;
case SeennErrorCode.invalidJobId:
print('Invalid job ID');
break;
case SeennErrorCode.bridgeNotRegistered:
print('Native setup incomplete');
break;
default:
print('Error [${result.code}]: ${result.error}');
}
}
Android Ongoing Notification
// Start notification
await seenn.ongoingNotification.startNotification(
jobId: 'job_abc',
title: 'Processing',
message: 'Starting...',
);
// Update progress
await seenn.ongoingNotification.updateNotification(
jobId: 'job_abc',
progress: 50,
message: 'Halfway there...',
);
// End notification
await seenn.ongoingNotification.endNotification(
jobId: 'job_abc',
title: 'Complete',
message: 'Your video is ready!',
);
Cross-Platform Notifications
Use JobNotificationService for unified iOS + Android handling:
// Automatically uses Live Activity on iOS, Ongoing Notification on Android
await seenn.jobNotification.startNotification(
jobId: 'job_abc',
title: 'Processing',
message: 'Starting...',
);
// Sync with job updates
await seenn.jobNotification.syncWithJob(job);
ETA Countdown
// Get countdown stream
final countdown = etaCountdownStream(
job: job,
intervalMs: 1000,
);
countdown.listen((state) {
print('Remaining: ${state.formatted}'); // "2:34"
print('Past due: ${state.isPastDue}');
print('Confidence: ${state.confidence}'); // 0.0 - 1.0
});
Parent-Child Jobs
// Get parent jobs
final parents = seenn.jobs.parents;
// Get children of a parent
final children = seenn.jobs.childrenOf('parent_job_id');
// Stream child progress
tracker.onChildProgress.listen((update) {
print('${update.completed}/${update.total} complete');
print('${update.failed} failed');
});
Job Filtering
// By status
final active = seenn.jobs.active;
final completed = seenn.jobs.byStatus(JobStatus.completed);
// Reactive streams
seenn.jobs.active$.listen((jobs) {
print('Active jobs: ${jobs.length}');
});
Connection Management
// Check connection state
seenn.connection$.listen((state) {
print('Connected: ${state.isConnected}');
});
// Manual reconnect
await seenn.reconnect();
// Disconnect
await seenn.disconnect();
Documentation
Requirements
- Flutter >= 3.10.0
- Dart >= 3.0.0
- iOS 16.2+ (for Live Activity with push updates)
- Android API 21+ (for Ongoing Notification)
Why iOS 16.2? While Live Activities were introduced in iOS 16.1, the push token API (
pushType: .token) andActivityContentstruct required for remote backend updates were added in iOS 16.2.
License
MIT License - see LICENSE for details.
Libraries
- seenn_flutter
- Seenn Flutter SDK Real-time job progress tracking with Polling, Live Activity (iOS), and Ongoing Notification (Android) support.