The Storyteller class exposes a broad set of utilities on top of the primary widgets. This page highlights the most popular calls grouped by scenario. All methods live in package:storyteller_sdk/storyteller_sdk.dart.
Initialize successfully before calling these methods. Use Getting Started for setup and Troubleshooting for loading or channel failures.
Installation examples use Flutter 12.2.0 (Android 12.2.0 / iOS 11.9.1).
The ad-placement defaults, provider ordering and Clips-count comparisons below
were audited against an earlier 12.1.2 development snapshot (Android 12.1.2 /
iOS 11.8.0) and published 11.6.5 (Android 11.6.4 / iOS 11.6.1).
Those audit versions are distinct from the released native dependency pins;
check Changelog for your release.
Future<bool> Storyteller.isInitialized() – check whether the native SDK has finished initialising.
Future<bool> Storyteller.isPlayerVisible() / isPresentingContent() – aliases that report whether Storyteller content is currently presented on either platform.
Future<bool> Storyteller.isPlayerMuted() – reads the current player mute state on iOS. Android throws a PlatformException with code UNSUPPORTED_PLATFORM because its native SDK has no public getter.
Future<void> Storyteller.mute() / unmute() – mute or unmute Story and Clip audio without pausing or resuming playback, on Android and iOS. Call after initialisation; with no player open, the choice applies to the next Story or Clip. Both throw a PlatformException with code AUDIO_CONTROL_ERROR before initialisation.
Future<void> Storyteller.dismissPlayer({bool animated = true, String? dismissReason}) – close the player programmatically. iOS applies animated and dismissReason; Android currently ignores both arguments.
Future<void> Storyteller.resumePlayer() – resume playback after dismissing your custom share UI. This is not a general-purpose pause/resume lifecycle API; use the Embedded Clips controller for inline playback.
Future<void> Storyteller.setUseCustomShareHandling(bool enabled) – let your app handle Storyteller share button taps instead of the native share sheet.
Future<void> Storyteller.openStory(String id, {StorytellerOpenReason? openReason}) – open a specific story by Storyteller identifier.
Future<void> Storyteller.openStoryByExternalId(String externalId, {StorytellerOpenReason? openReason}) – open a story using the external identifier you provided to Storyteller.
Future<void> Storyteller.openPage(String id, {StorytellerOpenReason? openReason}) / openSheet(String id) – open a particular page or sheet on iOS. Android opens pages but its current Flutter openSheet handler performs no action.
Future<void> Storyteller.openCategory(String category, {StorytellerOpenReason? openReason}) – launch the player scoped to a Storyteller category.
Future<void> Storyteller.openCollection(String id, {String? clipId, StorytellerTheme? theme, StorytellerOpenReason? openReason, StorytellerClipsAdConfiguration? adConfiguration, String? requestId}) – present a collection, optionally jump to a clip, and override ad-placement controls for that presentation.
Future<void> Storyteller.openCollectionWithCategory(String id, {String? category, StorytellerTheme? theme, StorytellerOpenReason? openReason, StorytellerClipsAdConfiguration? adConfiguration, String? requestId}) – apply an additional category filter when opening a collection.
Future<void> Storyteller.openClipByExternalId(String collectionId, String externalId, {StorytellerOpenReason? openReason, String? requestId}) – target a clip referenced by your external identifier within a collection. openCollectionByExternalId(...) is an equivalent Android-native naming alias.
Future<void> Storyteller.openSearch() and Future<bool> Storyteller.isSearchEnabled() – launch Storyteller search when the native configuration allows it.
StorytellerOpenReason.instanceMethod and StorytellerOpenReason.deeplink let you explicitly attribute a direct open. Omit openReason to preserve the default of the native entry point. For Clips collection opens, that omitted default is deeplink on Android and instanceMethod on iOS. Android's external-ID collection API always uses its native deep-link reason, so passing instanceMethod to either external-ID Clips alias throws UNSUPPORTED_ARGUMENT on Android.
StorytellerClipsAdConfiguration has nullable preRollEnabled,
bottomBannerEnabled, betweenClipsAdProviderOrder, frequency,
initialIndex, and bottomBannerFetchMode fields. Omit the entire object, or
an individual field, to keep the linked native SDK's default for that platform
and presentation type. Pre-roll is supported on Android and iOS;
Android defaults it on and iOS defaults it off in both compared baselines. Provider ordering
is Android-only: null preserves native module order, an empty list disables
standard providers, and a populated list restricts and orders VAST, GAM, and
AdMob. iOS ignores provider ordering. Also Android-only: a positive frequency
and a non-negative initialIndex override the remote between-Clips cadence for
that presentation (initialIndex0 is the opening-ad position; positive
values are one-based content positions), and bottomBannerFetchMode selects
justInTime (the native default) or prefetch, which prepares the next Clip's
bottom banner while the current Clip plays. iOS ignores these three fields. The theme argument on openCollection and openCollectionWithCategory is applied on iOS; the current Android bridge ignores it, so use a global theme for Android.
For 11.6.5 and 12.1.2 at the native versions above,
the effective defaults are:
Presentation
Android 11.6.4 / 12.1.2 pre-roll / bottom banner
iOS 11.6.1 / 11.8.0 pre-roll / bottom banner
Direct Clips collection open
true / true
false / false
Embedded Clips
true / false
false / false
Player opened from Clips list
true / true
Flutter list ad configuration ignored
The Dart ad configuration fields default to null; those are bridge omissions, not false values.
Clips open calls generate a request ID when one is not supplied. Invalid arguments and native failures that complete the call reject its Future. Android can additionally report callback-style failures through Storyteller.onClipsOpenError, potentially after the Future completes, so subscribe before opening when those events matter. Correlate stream events using StorytellerOpenError.requestId; each event exposes only the request ID, operation, and allowlisted error code.
For an explicit per-presentation override after initialization:
Placement flags allow eligible ads; an enabled flag does not register a provider or guarantee ad fill. See Ads for module registration and provider selection.
Future<bool> Storyteller.isStorytellerDeeplink(String url) / isStorytellerDeepLink(String url) – equivalent spelling aliases that detect whether a URL should be handled by Storyteller.
Future<void> Storyteller.openDeeplink(String url) / openDeepLink(String url) – equivalent spelling aliases that forward Storyteller URLs to the native SDK.
Stream<String> Storyteller.userNavigatedToApp – emits URLs when a user taps a Storyteller deep link that should be handled by your Flutter router.
See Deep Linking for end-to-end integration guidance.
Future<String> Storyteller.version() – read the linked native SDK version, which may differ between Android and iOS and from the Flutter package version.
Future<String> Storyteller.currentApiKey() – read the current native API key. Keep this value out of logs and analytics.
Stream<StorytellerUserActivityEvent> Storyteller.onUserActivityOccurred – receive detailed interaction payloads for analytics use-cases.
Stream<StorytellerShareEvent> Storyteller.onShareButtonTapped – receive share button payloads after enabling custom share handling.
Future<int> Storyteller.getStoriesCount(List<String> categoryIds) – fetch the number of stories for the supplied categories.
Future<int> Storyteller.getClipsCount(String collectionId) – fetch a Clips count using the source-compatible helper. iOS treats the value as a collection ID; Android treats it as a single category ID in both compared baselines.
Future<int> Storyteller.getClipsCountForCategories(List<String> categoryIds) – fetch a Clips count for categories on Android. iOS throws UNSUPPORTED_PLATFORM.
Future<String?> Storyteller.preloadClips(String collectionId, {List<String> clipIds = const [], bool preloadVideos = false}) – begin Android Clips preloading and return an opaque cancellation handle. iOS returns null because it has no public native preloader.
Future<void> Storyteller.cancelPreloadClips(String handle) – cancel and release an Android preload handle. It is a no-op on iOS.
Future<StorytellerEventTrackingOptions> Storyteller.eventTrackingOptions() – inspect the current tracking configuration.
Stream<String> Storyteller.onLog – subscribe to iOS native SDK log output. Android exposes the stream but the current bridge does not emit messages; inspect Android native logs when debugging.
Future<void> Storyteller.addFollowedCategory(String category) / addFollowedCategories(List<String>) – mark categories as followed for the current user.
Future<void> Storyteller.removeFollowedCategory(String category) / removeFollowedCategories(List<String>) – remove one or more followed categories.
Future<void> Storyteller.setFollowedCategories(List<String> categories) – replace the followed-category set and await native category resolution. Unknown IDs are omitted from the resolved subset; a request failure throws and preserves the previous native state.
Future<List<String>> Storyteller.followedCategories() – read the current list, typically to sync with your own profile service.
Future<bool> Storyteller.isCategoryFollowed(String categoryId) – convenience helper for toggles.
Future<StorytellerFollowableCategories> Storyteller.getFollowableCategories() – fetch a flat categories list of StorytellerFollowableCategory values, including isFollowed and optional placement metadata.
Stream<CategoryFollowEvent> Storyteller.categoryFollowActionTaken – observe follow/unfollow events triggered from Storyteller UI.
Future<void> Storyteller.setTheme(StorytellerTheme theme) – override colours and typography for any subsequent Storyteller UI. Build the theme map using StorytellerTheme helpers or JSON.
Future<void> Storyteller.setLocale(String? locale) – override the language using an ISO language code (e.g. "en") or pass null to clear the override and return locale selection to the native SDK.
Each method returns a Future that completes when the native method channel responds. For presentation and reload methods, this does not guarantee content is visible or loading has completed. The add/remove follow methods start native asynchronous work; setFollowedCategories awaits resolution. Follow mutations require tenant configuration for app-managed following. See Working with Users. Wrap your invocations in try/catch blocks to surface platform exceptions gracefully.
{"slug": "additional-methods", "page_title": "Additional Methods", "page_url": "AdditionalMethods/", "canonical_url": "/flutter/AdditionalMethods/", "markdown": "# Additional Methods\n\nThe `Storyteller` class exposes a broad set of utilities on top of the primary widgets. This page highlights the most popular calls grouped by scenario. All methods live in `package:storyteller_sdk/storyteller_sdk.dart`.\n\nInitialize successfully before calling these methods. Use [Getting Started](getting-started/index.md) for setup and [Troubleshooting](Troubleshooting.md) for loading or channel failures.\n\nInstallation examples use Flutter `12.2.0` (Android `12.2.0` / iOS `11.9.1`).\nThe ad-placement defaults, provider ordering and Clips-count comparisons below\nwere audited against an earlier `12.1.2` development snapshot (Android `12.1.2` /\niOS `11.8.0`) and published `11.6.5` (Android `11.6.4` / iOS `11.6.1`).\nThose audit versions are distinct from the released native dependency pins;\ncheck [Changelog](Changelog.md) for your release.\n\n## Player status & control\n\n- `Future<bool> Storyteller.isInitialized()` \u2013 check whether the native SDK has finished initialising.\n- `Future<bool> Storyteller.isPlayerVisible()` / `isPresentingContent()` \u2013 aliases that report whether Storyteller content is currently presented on either platform.\n- `Future<bool> Storyteller.isPlayerMuted()` \u2013 reads the current player mute state on iOS. Android throws a `PlatformException` with code `UNSUPPORTED_PLATFORM` because its native SDK has no public getter.\n- `Future<void> Storyteller.mute()` / `unmute()` \u2013 mute or unmute Story and Clip audio without pausing or resuming playback, on Android and iOS. Call after initialisation; with no player open, the choice applies to the next Story or Clip. Both throw a `PlatformException` with code `AUDIO_CONTROL_ERROR` before initialisation.\n- `Future<void> Storyteller.dismissPlayer({bool animated = true, String? dismissReason})` \u2013 close the player programmatically. iOS applies `animated` and `dismissReason`; Android currently ignores both arguments.\n- `Future<void> Storyteller.resumePlayer()` \u2013 resume playback after dismissing your custom share UI. This is not a general-purpose pause/resume lifecycle API; use the Embedded Clips controller for inline playback.\n- `Future<void> Storyteller.setUseCustomShareHandling(bool enabled)` \u2013 let your app handle Storyteller share button taps instead of the native share sheet.\n\n## Navigation helpers\n\n- `Future<void> Storyteller.openStory(String id, {StorytellerOpenReason? openReason})` \u2013 open a specific story by Storyteller identifier.\n- `Future<void> Storyteller.openStoryByExternalId(String externalId, {StorytellerOpenReason? openReason})` \u2013 open a story using the external identifier you provided to Storyteller.\n- `Future<void> Storyteller.openPage(String id, {StorytellerOpenReason? openReason})` / `openSheet(String id)` \u2013 open a particular page or sheet on iOS. Android opens pages but its current Flutter `openSheet` handler performs no action.\n- `Future<void> Storyteller.openCategory(String category, {StorytellerOpenReason? openReason})` \u2013 launch the player scoped to a Storyteller category.\n- `Future<void> Storyteller.openCollection(String id, {String? clipId, StorytellerTheme? theme, StorytellerOpenReason? openReason, StorytellerClipsAdConfiguration? adConfiguration, String? requestId})` \u2013 present a collection, optionally jump to a clip, and override ad-placement controls for that presentation.\n- `Future<void> Storyteller.openCollectionWithCategory(String id, {String? category, StorytellerTheme? theme, StorytellerOpenReason? openReason, StorytellerClipsAdConfiguration? adConfiguration, String? requestId})` \u2013 apply an additional category filter when opening a collection.\n- `Future<void> Storyteller.openClipByExternalId(String collectionId, String externalId, {StorytellerOpenReason? openReason, String? requestId})` \u2013 target a clip referenced by your external identifier within a collection. `openCollectionByExternalId(...)` is an equivalent Android-native naming alias.\n- `Future<void> Storyteller.openSearch()` and `Future<bool> Storyteller.isSearchEnabled()` \u2013 launch Storyteller search when the native configuration allows it.\n\n`StorytellerOpenReason.instanceMethod` and `StorytellerOpenReason.deeplink` let you explicitly attribute a direct open. Omit `openReason` to preserve the default of the native entry point. For Clips collection opens, that omitted default is `deeplink` on Android and `instanceMethod` on iOS. Android's external-ID collection API always uses its native deep-link reason, so passing `instanceMethod` to either external-ID Clips alias throws `UNSUPPORTED_ARGUMENT` on Android.\n\n`StorytellerClipsAdConfiguration` has nullable `preRollEnabled`,\n`bottomBannerEnabled`, `betweenClipsAdProviderOrder`, `frequency`,\n`initialIndex`, and `bottomBannerFetchMode` fields. Omit the entire object, or\nan individual field, to keep the linked native SDK's default for that platform\nand presentation type. Pre-roll is supported on Android and iOS;\nAndroid defaults it on and iOS defaults it off in both compared baselines. Provider ordering\nis Android-only: `null` preserves native module order, an empty list disables\nstandard providers, and a populated list restricts and orders VAST, GAM, and\nAdMob. iOS ignores provider ordering. Also Android-only: a positive `frequency`\nand a non-negative `initialIndex` override the remote between-Clips cadence for\nthat presentation (`initialIndex` `0` is the opening-ad position; positive\nvalues are one-based content positions), and `bottomBannerFetchMode` selects\n`justInTime` (the native default) or `prefetch`, which prepares the next Clip's\nbottom banner while the current Clip plays. iOS ignores these three fields. The `theme` argument on `openCollection` and `openCollectionWithCategory` is applied on iOS; the current Android bridge ignores it, so use a global theme for Android.\n\nFor `11.6.5` and `12.1.2` at the native versions above,\nthe effective defaults are:\n\n| Presentation | Android 11.6.4 / 12.1.2 pre-roll / bottom banner | iOS 11.6.1 / 11.8.0 pre-roll / bottom banner |\n| --- | --- | --- |\n| Direct Clips collection open | `true` / `true` | `false` / `false` |\n| Embedded Clips | `true` / `false` | `false` / `false` |\n| Player opened from Clips list | `true` / `true` | Flutter list ad configuration ignored |\n\nThe Dart ad configuration fields default to `null`; those are bridge omissions, not `false` values.\n\nClips open calls generate a request ID when one is not supplied. Invalid arguments and native failures that complete the call reject its `Future`. Android can additionally report callback-style failures through `Storyteller.onClipsOpenError`, potentially after the `Future` completes, so subscribe before opening when those events matter. Correlate stream events using `StorytellerOpenError.requestId`; each event exposes only the request ID, operation, and allowlisted error code.\n\nFor an explicit per-presentation override after initialization:\n\n```dart\nawait Storyteller.openCollection(\n 'YOUR_COLLECTION_ID',\n adConfiguration: const StorytellerClipsAdConfiguration(\n preRollEnabled: true,\n bottomBannerEnabled: true,\n betweenClipsAdProviderOrder: [StorytellerAdProvider.gam],\n ),\n);\n```\n\nPlacement flags allow eligible ads; an enabled flag does not register a provider or guarantee ad fill. See [Ads](Ads.md) for module registration and provider selection.\n\n## Deep links\n\n- `Future<bool> Storyteller.isStorytellerDeeplink(String url)` / `isStorytellerDeepLink(String url)` \u2013 equivalent spelling aliases that detect whether a URL should be handled by Storyteller.\n- `Future<void> Storyteller.openDeeplink(String url)` / `openDeepLink(String url)` \u2013 equivalent spelling aliases that forward Storyteller URLs to the native SDK.\n- `Stream<String> Storyteller.userNavigatedToApp` \u2013 emits URLs when a user taps a Storyteller deep link that should be handled by your Flutter router.\n\nSee [Deep Linking](Deeplinking.md) for end-to-end integration guidance.\n\n## SDK diagnostics\n\n- `Future<String> Storyteller.version()` \u2013 read the linked native SDK version, which may differ between Android and iOS and from the Flutter package version.\n- `Future<String> Storyteller.currentApiKey()` \u2013 read the current native API key. Keep this value out of logs and analytics.\n\n## Analytics & counts\n\n- `Stream<StorytellerUserActivityEvent> Storyteller.onUserActivityOccurred` \u2013 receive detailed interaction payloads for analytics use-cases.\n- `Stream<StorytellerShareEvent> Storyteller.onShareButtonTapped` \u2013 receive share button payloads after enabling custom share handling.\n- `Future<int> Storyteller.getStoriesCount(List<String> categoryIds)` \u2013 fetch the number of stories for the supplied categories.\n- `Future<int> Storyteller.getClipsCount(String collectionId)` \u2013 fetch a Clips count using the source-compatible helper. iOS treats the value as a collection ID; Android treats it as a single category ID in both compared baselines.\n- `Future<int> Storyteller.getClipsCountForCategories(List<String> categoryIds)` \u2013 fetch a Clips count for categories on Android. iOS throws `UNSUPPORTED_PLATFORM`.\n- `Future<String?> Storyteller.preloadClips(String collectionId, {List<String> clipIds = const [], bool preloadVideos = false})` \u2013 begin Android Clips preloading and return an opaque cancellation handle. iOS returns `null` because it has no public native preloader.\n- `Future<void> Storyteller.cancelPreloadClips(String handle)` \u2013 cancel and release an Android preload handle. It is a no-op on iOS.\n- `Future<StorytellerEventTrackingOptions> Storyteller.eventTrackingOptions()` \u2013 inspect the current tracking configuration.\n- `Stream<String> Storyteller.onLog` \u2013 subscribe to iOS native SDK log output. Android exposes the stream but the current bridge does not emit messages; inspect Android native logs when debugging.\n\n## Categories & following\n\n- `Future<void> Storyteller.addFollowedCategory(String category)` / `addFollowedCategories(List<String>)` \u2013 mark categories as followed for the current user.\n- `Future<void> Storyteller.removeFollowedCategory(String category)` / `removeFollowedCategories(List<String>)` \u2013 remove one or more followed categories.\n- `Future<void> Storyteller.setFollowedCategories(List<String> categories)` \u2013 replace the followed-category set and await native category resolution. Unknown IDs are omitted from the resolved subset; a request failure throws and preserves the previous native state.\n- `Future<List<String>> Storyteller.followedCategories()` \u2013 read the current list, typically to sync with your own profile service.\n- `Future<bool> Storyteller.isCategoryFollowed(String categoryId)` \u2013 convenience helper for toggles.\n- `Future<StorytellerFollowableCategories> Storyteller.getFollowableCategories()` \u2013 fetch a flat `categories` list of `StorytellerFollowableCategory` values, including `isFollowed` and optional placement metadata.\n- `Stream<CategoryFollowEvent> Storyteller.categoryFollowActionTaken` \u2013 observe follow/unfollow events triggered from Storyteller UI.\n\n## Appearance & localisation\n\n- `Future<void> Storyteller.setTheme(StorytellerTheme theme)` \u2013 override colours and typography for any subsequent Storyteller UI. Build the theme map using `StorytellerTheme` helpers or JSON.\n- `Future<void> Storyteller.setLocale(String? locale)` \u2013 override the language using an ISO language code (e.g. `\"en\"`) or pass `null` to clear the override and return locale selection to the native SDK.\n\nEach method returns a `Future` that completes when the native method channel responds. For presentation and reload methods, this does not guarantee content is visible or loading has completed. The add/remove follow methods start native asynchronous work; `setFollowedCategories` awaits resolution. Follow mutations require tenant configuration for app-managed following. See [Working with Users](Users.md). Wrap your invocations in `try/catch` blocks to surface platform exceptions gracefully.\n", "copy_markdown_include_header": false, "base_path": "", "ai_dir": "ai", "missing_payload_behavior": "empty"}