This project is a host application example for the YouScribe Flutter SDK.
It is intentionally built with as few dependencies as possible so the SDK integration stays easy to read. The app demonstrates the complete host-side flow described in INTEGRATION.md: authentication, SDK initialization, token refresh, product opening, download orchestration, cache inspection, file deletion, and event logging.
The UI is intentionally split in two layers:
- a simple reader-first path centered on
productId -> YouScribeReader; - a second layer exposing the programmatic SDK APIs with inline explanations.
- SDK initialization with
YouScribeSDK.initialize(). - Host-managed authentication with lib/src/api.dart using a generic identifier.
- Auth token propagation with
updateAuthToken(). - Product preflight with
readProduct(). - Reader launch with
YouScribeReader(productId: ...). - PDF reader lifecycle hooks through
PdfReadingHooks. - Download start with
download(productId: ...). - Download resume with
trackDownload(productId: ...). - Global active download observation with
watchActiveDownloads(). - Direct task cancellation with
DownloadTask.cancel(). - SDK-level cancellation with
stopDownload(productId). - Cache checks with
isFileAvailable()andgetDownloadedFiles(). - File cleanup with
deleteFile(productId: ...). - SDK event monitoring with
YouScribeSDK.instance.events. - Host-driven token refresh using the SDK
onTokenExpiredcallback.
The example keeps a small, explicit architecture:
- lib/main.dart: application bootstrap.
- lib/src/app/demo_app.dart: app theme and root widget.
- lib/src/app/demo_controller.dart: the single source of truth for host state, SDK calls, token refresh, download tracking, and event logging.
- lib/src/app/demo_page.dart: responsive demo UI.
- lib/src/app/demo_models.dart: small app-specific models.
- lib/src/api.dart: host authentication helper used by the demo.
This structure keeps the responsibilities clear:
- the host app owns authentication;
- the controller owns orchestration and state transitions;
- the UI stays focused on presenting the SDK features.
The SDK does not manage sign-in, so this example uses lib/src/api.dart to authenticate against the YouScribe API and retrieve an auth token.
The sign-in field is intentionally labeled identifier instead of email , because the backend endpoint accepts a generic identifier.
For the demo only, the password is kept in memory after sign-in so the onTokenExpired callback can re-authenticate through the same host flow. In a production host application you should replace this with your own secure refresh-token strategy.
This demo does not tie authentication to updateLocalDataDiscriminator() . The SDK keeps its active local scope as-is during sign-in and sign-out.
The app first emphasizes the simplest integration path:
- authenticate the host app;
- enter a product ID;
- open
YouScribeReader.
That is the path most host applications should start with because the SDK manages the reader-opening flow for you.
The programmatic section remains available underneath and documents when to use:
isFileAvailable()readProduct()download()trackDownload()DownloadTask.cancel()stopDownload()
Each action is described directly in the UI so the demo can be used as a guided integration reference.
The SDK is published on a private Dart registry. The example app declares youscribe_sdk and also adds dependency_overrides for the private transitive packages so flutter pub get resolves them from the same registry:
youscribe_audio_playeryouscribe_epub_readeryouscribe_pdf_reader
Without those overrides, pub attempts to resolve some transitive packages from pub.dev and dependency resolution fails.
The Android host app is configured for the Nutrient-backed PDF reader used by the SDK:
compileSdk = 36minSdk = 24- Java 17 and Kotlin JVM 17
androidx.appcompatdependency- direct
io.nutrient:nutrient:11.2.1visibility forFlutterAppCompatActivity FlutterAppCompatActivityPSPDFKit.Theme.Defaultas the Android normal themeback_icon.xmlin the drawable resourcesINTERNETpermission in the main manifest
These changes are already applied in this example project.
The integration guide currently mentions compileSdkVersion 35 as a baseline, but the current resolved plugin set used by this example requires Android SDK 36. The active Nutrient Flutter plugin also targets minSdk 24 , so the example app is pinned to those working values.
- Install dependencies:
flutter pub get- Launch the app:
flutter run- Sign in with a YouScribe account in the demo UI.
- Enter a product ID that the authenticated account can access.
- Start with
Open with YouScribeReader. - Then explore the programmatic actions if your host app needs finer control:
Check availability
Call readProduct()
Download
Temporary download
Track existing download
Cancel tracked task
Stop download
- Inspect the downloaded files and the event log to understand how the SDK behaves inside a host application.
- The sample product ID shown in the UI is only a placeholder.
- The app focuses on clarity over abstraction-heavy patterns.
- The example uses only Flutter framework primitives for state management.
- The demo is designed to complement the SDK documentation, not replace your app-specific architecture.
The project was validated with:
flutter analyze