### E-commerce Page Setup for Macros Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration Example of setting up product data on an e-commerce page. This data can then be used in macro configurations for ad targeting. ```javascript // Page setup window.productData = { category: 'electronics', price: '499.99', }; ``` -------------------------------- ### News/Media Site Page Setup for Macros Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration Example of setting up article data on a news or media site. This data can be mapped to macros for content-specific ad targeting. ```javascript // Page setup window.articleData = { topic: 'sports', author: 'john-doe', }; ``` -------------------------------- ### StorifyMe Event Listener Setup Source: https://docs.storifyme.com/stories/android-sdk/android-events This is the main example showing how to set up a comprehensive event listener for StorifyMe. It covers multiple event callbacks for various user interactions and story states. ```APIDOC ## StorifyMe Event Listener Setup ### Description This example demonstrates how to attach a `StorifyMeEventListener` to the `StorifyMe.instance`. This listener allows you to intercept and handle various events that occur within the StorifyMe stories, such as loading, errors, story openings, closings, actions, and more. ### Method `StorifyMe.instance.eventListener = object : StorifyMeEventListener() { ... }` ### Endpoint N/A (This is a client-side SDK configuration) ### Parameters This section describes the methods available within the `StorifyMeEventListener`. #### onLoad(widgetId: Long, stories: List) Invoked when the widget loads successfully. #### onFail(error: StorifyMeError) Invoked when the widget loading fails. Useful for error handling and retries. #### onStoryOpened(story: StoryWithSeen, index: Int) Invoked when a user opens a story. #### onStoryClosed(story: StoryWithSeen) Invoked when the user closes the story viewer. #### onAction(type: String, data: JSONObject) Invoked when the user interacts with engaging components (e.g., buttons, quizzes). Allows overriding default actions. #### onEvent(type: String, data: JSONObject) Generic event handler for custom events. #### onShopping(type: String, data: JSONObject) Handler for shopping-related events. #### onStoryShared(story: StoryWithSeen) Invoked when a story is shared. #### onStoryDeeplinkTriggered(story: StoryWithSeen, completion: (StorifyMeStoryDeeplinkTriggerCompletion) -> Unit) Invoked when a story deeplink is triggered. Allows controlling whether the story viewer should be presented. #### onLinkOpenTriggered(url: String, completion: (StorifyMeLinkTriggerCompletion) -> Unit) Invoked when a link within a story is triggered. Allows controlling the default link opening behavior. ### Request Example ```kotlin StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onLoad(widgetId: Long, stories: List) { Log.d(TAG, "onLoad() - widgetId: $widgetId - ${stories.joinToString()}") } override fun onFail(error: StorifyMeError) { Log.d(TAG, "onFail() - ${error.message} - ${error.type}") } override fun onStoryOpened(story: StoryWithSeen, index: Int) { Log.d(TAG, "onStoryOpened() $story : index: $index") } override fun onStoryClosed(story: StoryWithSeen) { Log.d(TAG, "onStoryClosed() $story") } override fun onAction(type: String, data: JSONObject) { Log.d(TAG, "onAction() - type: $type - data: $action") } override fun onEvent(type: String, data: JSONObject) { Log.d(TAG, "onEvent() - type: $type - data: $data") } override fun onShopping(type: String, data: JSONObject) { Log.d(TAG, "onShopping() - type: $type - data: $data") } override fun onStoryShared(story: StoryWithSeen) { Log.d(TAG, "onStoryShared() $story") } override fun onStoryDeeplinkTriggered( story: StoryWithSeen, completion: (StorifyMeStoryDeeplinkTriggerCompletion) -> Unit ) { if (checkSomeCondition) { completion(StorifyMeStoryDeeplinkTriggerCompletion.IGNORE_PRESENTING_STORY) } else { completion(StorifyMeStoryDeeplinkTriggerCompletion.OPEN_STORY_BY_DEFAULT) } } override fun onLinkOpenTriggered( url: String, completion: (StorifyMeLinkTriggerCompletion) -> Unit ) { if (checkSomeCondition) { completion(StorifyMeLinkTriggerCompletion.IGNORE_PRESENTING_LINK) } else { completion(StorifyMeLinkTriggerCompletion.OPEN_LINK_BY_DEFAULT) } } } ``` ### Response N/A (This is a configuration step, not an API call with a direct response.) ``` -------------------------------- ### Complete Migration Example: After (Compose) Source: https://docs.storifyme.com/stories/android-sdk/android-compose This is the 'after' state of a migration example, showing an Activity using Compose and the declarative StorifyMe integration. ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyAppTheme { StoriesScreen() } } } } @Composable fun StoriesScreen() { val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } val config = rememberStoriesViewConfig( language = "en", segments = listOf("premium") ) Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) }) { StoriesView( widgetId = 12345, config = config, loadEventCallbacks = StorifyMeLoadEventCallbacks( onLoad = { _, stories -> scope.launch { snackbarHostState.showSnackbar("Loaded ${stories.size} stories") } } ), lifecycleCallbacks = StorifyMeLifecycleCallbacks( onStoryOpened = { story, _ -> Log.d("Stories", "Opened: ${story.story.name}") } ), modifier = Modifier .fillMaxWidth() .padding(it) ) } } ``` -------------------------------- ### Complete Migration Example: Before (Activity with XML) Source: https://docs.storifyme.com/stories/android-sdk/android-compose This is the 'before' state of a migration example, showing an Activity using XML layouts and the imperative StorifyMe View. ```kotlin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val storiesView = findViewById(R.id.storiesView) val config = StorifyMeWidgetConfig.Builder().apply { setLanguage("en") setSegments(listOf("premium")) }.build() storiesView.config = config storiesView.widgetId = 12345 storiesView.load() StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onLoad(widgetId: Long, stories: List) { Toast.makeText(this@MainActivity, "Loaded ${stories.size} stories", Toast.LENGTH_SHORT).show() } override fun onStoryOpened(story: StoryWithSeen, index: Int) { Log.d("Stories", "Opened: ${story.story.name}") } } } } ``` -------------------------------- ### Apply compact layout configuration Source: https://docs.storifyme.com/stories/web-sdk/web-setup-widget Example of creating a compact widget layout. ```css story-widget { --storify-vertical-spacing: 10px; --storify-horizontal-spacing: 10px; --storify-item-gap: 15px; --storify-title-size: 1rem; } ``` -------------------------------- ### Apply minimal style configuration Source: https://docs.storifyme.com/stories/web-sdk/web-setup-widget Example of creating a minimal widget appearance. ```css story-widget { --storify-background: transparent; --storify-vertical-spacing: 0; --storify-item-gap: 20px; --storify-item-radius: 16px; } ``` -------------------------------- ### Widget Loading and Integration Example Source: https://docs.storifyme.com/stories/android-sdk/android-personalization A complete example demonstrating the integration of StorifyMe widget in an Android Activity, including configuration and loading. ```APIDOC ## Complete Widget Integration Example ### Description This example shows a full integration of the StorifyMe widget within an Android `AppCompatActivity`, covering widget configuration, user ID setting for personalization, and loading the widget. ### Method `StoriesView.load()` ### Endpoint N/A (Client-side integration) ### Request Example ```kotlin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val storiesView = findViewById(R.id.storiesView) // Configure widget with base segments val config = StorifyMeWidgetConfig.Builder() .setSegments(listOf("mobile_app_users")) .setCustomerId("customer-123") .build() lifecycleScope.launch { // Resolve CDP audience segments for this user storiesView.setSegmentUserId("user@example.com") // Apply widget configuration storiesView.config = config // Load widget with personalized content storiesView.load() } } } ``` ``` -------------------------------- ### Verify StorifyMe Import and Initialization Source: https://docs.storifyme.com/stories/ios-sdk Example of the import statement and initialization code for the StorifyMe SDK after installation. No code changes are needed if migrating from other installation methods. ```swift import StorifyMe // Same import - no code changes needed! // All your existing code works identically: StorifyMeInstance.shared.initialize( accountId: "YOUR_ACCOUNT_ID", apiKey: "YOUR_API_KEY", env: .EU ) ``` -------------------------------- ### Example Macro Object Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration An example of a Macro object configuration. This specific example matches '[page_url]' in the URL with the special value '[description_url]'. ```javascript { name: "page_url", // Matches [page_url] in URL value: "[description_url]" // Special value } ``` -------------------------------- ### Basic Ad Tag URL Setup Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration A standard video tag URL configuration using basic macros. ```text https://pubads.g.doubleclick.net/gampad/ads? description_url=[page]& correlator=[cache] ``` -------------------------------- ### Install StorifyMe Snaps SDK Source: https://docs.storifyme.com/snaps/web-sdk Include the SDK script and the custom element in your HTML to initialize the Snaps editor. ```html ``` -------------------------------- ### Install Flutter Dependencies Source: https://docs.storifyme.com/stories/flutter-sdk/flutter-deep-linking Command to fetch the newly added dependencies into your project. ```bash flutter pub get ``` -------------------------------- ### Complete StorifyMe Widget Integration Example Source: https://docs.storifyme.com/stories/android-sdk/android-personalization A complete example demonstrating the integration of the StorifyMe widget in an Android Activity. This includes setting up the widget with base segments, customer ID, resolving audience segments, and loading the widget with personalized content. ```kotlin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val storiesView = findViewById(R.id.storiesView) // Configure widget with base segments val config = StorifyMeWidgetConfig.Builder() .setSegments(listOf("mobile_app_users")) .setCustomerId("customer-123") .build() lifecycleScope.launch { // Resolve CDP audience segments for this user storiesView.setSegmentUserId("user@example.com") // Apply widget configuration storiesView.config = config // Load widget with personalized content storiesView.load() } } } ``` -------------------------------- ### Install StorifyMe SDK Source: https://docs.storifyme.com/stories/react-sdk Include the StorifyMe web components script in the HTML body. ```html ``` -------------------------------- ### Macro URL Transformation Example Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration Shows how placeholders in an ad URL are replaced with dynamic values. ```text Input: https://ads.example.com?page=[page_url]&time=[timestamp] Output: https://ads.example.com?page=https%3A%2F%2Fexample.com&time=1704123456789 ``` -------------------------------- ### Custom JavaScript Variable Examples Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration Examples of accessing custom values from the page using the window prefix. ```javascript window.myApp.userId; window.userData.subscription; window.IQD_varPack.iqd_TestKW; ``` -------------------------------- ### Initialize StorifyMe SDK and Display Widget Source: https://docs.storifyme.com/stories/ios-sdk/ios-swiftui Basic setup for initializing the SDK in your App struct and displaying a widget in ContentView. Ensure you replace placeholder credentials. ```swift @main struct MyApp: App { @StateObject private var sdkManager = StorifyMeSDKManager() init() { StorifyMeInstance.shared.initialize( accountId: "YOUR_ACCOUNT_ID", apiKey: "YOUR_API_KEY", env: .EU ) } var body: some Scene { WindowGroup { ContentView() .environmentObject(sdkManager) } } } struct ContentView: View { @EnvironmentObject var sdkManager: StorifyMeSDKManager var body: some View { Group { if sdkManager.isReady { StorifyMeWidgetView(widgetId: 54) } else { ProgressView("Loading SDK...") } } } } ``` -------------------------------- ### Branded Navigation Styling Source: https://docs.storifyme.com/stories/web-sdk/single-item-embed/web-styling Example configuration for branded navigation buttons. ```css storifyme-modal { --storify-modal-btn-background: #3498db; --storify-modal-btn-arrow-fill: white; } ``` -------------------------------- ### Configure Multiple Pins Source: https://docs.storifyme.com/guides/advanced-integration/custom-base-url-and-pinning Example of providing multiple pins to ensure continuity during certificate rotation. ```kotlin certificatePins = listOf( "sha256/CurrentCertificatePin=", // Active certificate "sha256/BackupCertificatePin=" // Backup for rotation ) ``` -------------------------------- ### Initialize StorifyMe SDK with Custom Domain and Pinning (Android) Source: https://docs.storifyme.com/guides/advanced-integration/custom-base-url-and-pinning Set up the StorifyMe SDK for enterprise deployment using a custom domain and certificate pinning. This example includes primary and backup certificate pins. ```kotlin StorifyMe.init( context = applicationContext, apiKey = "your-api-key", accountId = "your-account-id", environment = StorifyMeEnv.EU, customBaseUrl = "https://stories.yourcompany.com/", certificatePins = listOf( "sha256/PrimaryCertPin=", "sha256/BackupCertPin=" ) ) ``` -------------------------------- ### Setup StorifyMe Event Listener Source: https://docs.storifyme.com/stories/android-sdk/android-troubleshooting Implement the StorifyMeEventListener to track story openings and user actions. ```kotlin StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onStoryOpen(widgetId: Long, storyId: Long, storyHandle: String) { Log.d("StorifyMe", "Story opened: $storyHandle") } override fun onAction(widgetId: Long, storyId: Long, actionType: String, actionUrl: String) { Log.d("StorifyMe", "Action triggered: $actionType - $actionUrl") } } ``` -------------------------------- ### Advanced Ad Tag URL Setup Source: https://docs.storifyme.com/ads/web-sdk/macro-configuration A video tag URL configuration incorporating custom JavaScript variables. ```text https://pubads.g.doubleclick.net/gampad/ads? description_url=[page]& cust_params=kw%3D[keyword]& correlator=[time] ``` -------------------------------- ### Install StorifyMe SDK via Package Managers Source: https://docs.storifyme.com/snaps/react-native-sdk Use these commands to add the StorifyMe dependency to your project. Replace with the current release. ```bash npm install --save https://sdk.storifyme.com/react-native/react-native-storifyme-snaps-.tgz ``` ```bash yarn add https://sdk.storifyme.com/react-native/react-native-storifyme-snaps-.tgz ``` ```bash pnpm add https://sdk.storifyme.com/react-native/react-native-storifyme-snaps-.tgz ``` ```bash bun add https://sdk.storifyme.com/react-native/react-native-storifyme-snaps-.tgz ``` -------------------------------- ### Automatic Installation of StorifyMe Source: https://docs.storifyme.com/stories/web-sdk Include the script tag and the custom element in your HTML to automatically load the widget. ```html ``` -------------------------------- ### Implement Viafoura Authentication Flow Source: https://docs.storifyme.com/stories/web-sdk/integrations/viafoura A complete HTML example demonstrating how to initialize StorifyMe elements, handle user login/logout via Viafoura, and synchronize session cookies. ```html ``` -------------------------------- ### Initialize StorifyMe SDK with Certificate Pinning (Android) Source: https://docs.storifyme.com/guides/advanced-integration/custom-base-url-and-pinning Configure the StorifyMe SDK with a custom base URL and certificate pinning for enhanced security. This example demonstrates pinning both the leaf certificate and an intermediate certificate. ```kotlin StorifyMe.init( context = this, apiKey = "your-api-key", accountId = "your-account-id", environment = StorifyMeEnv.EU, customBaseUrl = "https://stories.yourapp.com", certificatePins = listOf( "sha256/[YOUR-LEAF-CERT-HASH]=", // From Step 1 "sha256/iFvwVyJSxnQdyaUvUERIf+8qk7gRze3612JMwoO3zdU=" // Let's Encrypt E8 ) ) ``` -------------------------------- ### Example SDK Log Output Format Source: https://docs.storifyme.com/stories/ios-sdk/ios-configuration Illustrates the format of log messages generated by the StorifyMe SDK, which includes the SDK name, log level, category, and the message content. ```text [StorifyMe] [LEVEL] [Category] Message ``` ```text [StorifyMe] [DEBUG] [Widget] Loading widget configuration ``` ```text [StorifyMe] [ERROR] [Network] Request failed: timeout ``` -------------------------------- ### Memory Monitor Usage in Activity Source: https://docs.storifyme.com/stories/android-sdk/android-performance Example of how to use the MemoryMonitor within an Activity. It starts monitoring on create and stops on destroy. If memory usage exceeds 80%, it optimizes for low memory. ```kotlin // Usage class StoriesActivity : AppCompatActivity() { private val memoryMonitor = MemoryMonitor() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) memoryMonitor.startMonitoring { status -> if (status.usagePercentage > 80) { // Switch to memory-optimized mode optimizeForLowMemory() } } } private fun optimizeForLowMemory() { storiesView.setGifPosterEnabled(false) storiesView.setVideoPosterEnabled(false) } override fun onDestroy() { memoryMonitor.stopMonitoring() super.onDestroy() } } ``` -------------------------------- ### Widget with Deep Link Handling Source: https://docs.storifyme.com/stories/android-sdk/android-compose Handle custom app deep links for navigation. This example shows how to intercept links starting with 'myapp://' and navigate to product pages or other app sections. ```kotlin @Composable fun DeepLinkWidget(navController: NavController) { val linkCallbacks = StorifyMeLinkInterceptionCallbacks( onLinkOpenTriggered = { url, completion -> when { url.startsWith("myapp://product/") -> { val productId = url.substringAfter("myapp://product/") navController.navigate("product/$productId") completion(StorifyMeLinkTriggerCompletion.IGNORE_PRESENTING_LINK) } url.startsWith("myapp://") -> { navController.navigate(url.substringAfter("myapp://")) completion(StorifyMeLinkTriggerCompletion.IGNORE_PRESENTING_LINK) } else -> { completion(StorifyMeLinkTriggerCompletion.OPEN_LINK_BY_DEFAULT) } } } ) StoriesView( widgetId = 12345, linkInterceptionCallbacks = linkCallbacks, modifier = Modifier.fillMaxWidth() ) } ``` -------------------------------- ### Clean CocoaPods Installation Source: https://docs.storifyme.com/stories/ios-sdk/ios-troubleshooting Commands to resolve common CocoaPods installation issues by clearing caches and re-integrating. ```bash # Clear CocoaPods cache pod cache clean --all pod deintegrate pod install --repo-update # If using Xcode 15+, you might need: pod install --verbose ``` -------------------------------- ### Initialize StorifyMe Snaps SDK Source: https://docs.storifyme.com/snaps/web-sdk Include the SDK script and initialize the SDK component in your HTML. Provide your account ID, API key, and environment. ```html ``` -------------------------------- ### Initialize SDK with Completion Handler Source: https://docs.storifyme.com/stories/ios-sdk/ios-configuration Initialize the SDK and handle the result via a completion handler, which executes on the main thread. ```swift StorifyMeInstance.shared.initialize( accountId: "YOUR_ACCOUNT_ID", apiKey: "YOUR_API_KEY", env: .EU ) { result in switch result { case .success: print("SDK initialized successfully") // Safe to use SDK features case .failure(let error): print("Initialization failed: \(error.message)") // Handle error appropriately } } ``` -------------------------------- ### Correct PreviewStoryByHandleLauncher Usage Source: https://docs.storifyme.com/stories/android-sdk/android-troubleshooting Use the correct import and singleton instance to launch story previews. ```kotlin // ❌ Wrong import import com.storifyme.PreviewStoryByHandleLauncher // ✅ Correct import import com.storify.android_sdk.PreviewStoryByHandleLauncher // ❌ Wrong usage PreviewStoryByHandleLauncher.launch(this, "handle") // ✅ Correct usage PreviewStoryByHandleLauncher.INSTANCE.launch(this, "handle") ``` -------------------------------- ### Install Required React Native Packages Source: https://docs.storifyme.com/stories/react-native-sdk/react-native-deep-linking Install dependencies for storage and splash screen management, including optional navigation packages. ```bash npm install @react-native-async-storage/async-storage react-native-bootsplash # For React Navigation (if using) npm install @react-navigation/native @react-navigation/native-stack react-native-screens ``` -------------------------------- ### Initialize Editor with Preloaded Templates Source: https://docs.storifyme.com/snaps/web-sdk Use the applyTemplates array within the snapsSdk.open configuration to define templates available to the user upon opening the editor. ```javascript // Button to open Snaps SDK const openSnapsBtn = document.querySelector('#openSnapsBtn'); openSnapsBtn.addEventListener('click', () => { // Open snaps command snapsSdk.open({ user: 'user-1', // User ID - can be any string you can use to identify the user on your side name: 'New snap', // Name of the new snap design tags: 'tag1,tag2', // (Optional) Comma separator tags for categorization of the new snap direction: 'ltr', // (Optional) Direction of the editor (ltr or rtl) language: 'en', // (Optional) Language of the new snap design applyTemplates: [ { id: 1, name: 'Template 1', preview_img: 'https://example.com/template1.png', tags: ['tag1', 'tag2'], description: 'This is template 1', configuration: { // Define the configuration of the template }, group_id: 'group1', count: 10, favorite: true, author: 'Author 1', author_img: 'https://example.com/author1.png', updated_at: new Date(), children: [ // Define child templates if applicable ], }, { id: 2, name: 'Template 2', preview_img: 'https://example.com/template2.png', tags: ['tag3', 'tag4'], description: 'This is template 2', configuration: { // Define the configuration of the template }, group_id: 'group2', count: 5, favorite: false, author: 'Author 2', author_img: 'https://example.com/author2.png', updated_at: new Date(), children: [ // Define child templates if applicable ], }, // Add more templates as needed ], }); }); ``` ```javascript // Button to open Snaps SDK const openSnapsBtn = document.querySelector('#openSnapsBtn'); openSnapsBtn.addEventListener('click', () => { // Open snaps command snapsSdk.open({ user: 'user-1', // User ID - can be any string you can use to identify the user on your side name: 'New snap', // Name of the new snap design tags: 'tag1,tag2', // (Optional) Comma separator tags for categorization of the new snap direction: 'ltr', // (Optional) Direction of the editor (ltr or rtl) language: 'en', // (Optional) Language of the new snap design applyTemplates: [ { id: 1, name: 'Template 1', preview_img: 'https://example.com/template1.png', tags: ['tag1', 'tag2'], description: 'This is template 1', configuration: { // Define the configuration of the template }, group_id: 'group1', count: 10, favorite: true, author: 'Author 1', author_img: 'https://example.com/author1.png', updated_at: new Date(), children: [ // Define child templates if applicable ], }, { id: 2, name: 'Template 2', preview_img: 'https://example.com/template2.png', tags: ['tag3', 'tag4'], description: 'This is template 2', configuration: { // Define the configuration of the template } ``` -------------------------------- ### Widget API: Get Paywall Status Source: https://docs.storifyme.com/stories/web-sdk/web-paywall Get the paywall status ('triggered', 'completed', or null) when the story is in an iframe (most common scenario). ```javascript widget.paywall.getStatus() ``` -------------------------------- ### Story Player API: Get Paywall Status Source: https://docs.storifyme.com/stories/web-sdk/web-paywall Get the paywall status ('triggered', 'completed', or null) when the story is directly embedded (not in an iframe). ```javascript window.storifyme.paywall.getStatus() ``` -------------------------------- ### Initialize and Load StoriesView Widget Source: https://docs.storifyme.com/stories/android-sdk/android-deep-linking Set up the StoriesView widget, attach an event listener, and load stories. Handles deep links by storing them if the widget is not yet loaded. ```kotlin class MainActivity : AppCompatActivity() { private lateinit var storiesView: StoriesView private var pendingHandle: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) storiesView = findViewById(R.id.storiesView) setupStoriesView() // Handle deep link handleDeepLink(intent) } private fun setupStoriesView() { StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onLoad(widgetId: Long, stories: List) { super.onLoad(widgetId, stories) // If we have a pending handle, open it now pendingHandle?.let { handle -> storiesView.openWidgetStoryByHandle(handle) { when (result) { is StorifyMeWidgetStoryNavigatorExecutionResult.Success -> { // Story opened successfully } is StorifyMeWidgetStoryNavigatorExecutionResult.StoryNotFound -> { // Handle not found in this widget // Consider using PreviewStoryByHandleLauncher as fallback PreviewStoryByHandleLauncher.INSTANCE.launch(this@MainActivity, handle) } is StorifyMeWidgetStoryNavigatorExecutionResult.WidgetNotLoaded -> { // Widget not ready yet } } } pendingHandle = null } } override fun onFail(widgetId: Long, error: String) { super.onFail(widgetId, error) // If widget fails to load but we have a handle, try direct launch pendingHandle?.let { handle -> PreviewStoryByHandleLauncher.INSTANCE.launch(this@MainActivity, handle) pendingHandle = null } } } storiesView.widgetId = YOUR_WIDGET_ID storiesView.load() } private fun handleDeepLink(intent: Intent) { val uri = intent.data if (uri != null) { val handle = extractStoryHandle(uri) if (handle != null) { if (storiesView.isLoaded()) { // Widget is already loaded, open immediately storiesView.openWidgetStoryByHandle(handle) } else { // Store handle to open after widget loads pendingHandle = handle } } } } } ``` -------------------------------- ### Switch Account with SDK Shutdown and Re-initialization Source: https://docs.storifyme.com/stories/ios-sdk/ios-configuration Demonstrates how to switch user accounts by first shutting down the current SDK instance and then re-initializing it with new credentials. This ensures a clean state before loading new account data. ```swift func switchAccount(to newAccountId: String, apiKey: String) { StorifyMeInstance.shared.shutdown { [weak self] in // Re-initialize with new credentials StorifyMeInstance.shared.initialize( accountId: newAccountId, apiKey: apiKey, env: .EU ) { result in switch result { case .success: self?.reloadAllWidgets() case .failure(let error): self?.showError(error) } } } } ``` -------------------------------- ### Dark Modal Theme Source: https://docs.storifyme.com/stories/web-sdk/single-item-embed/web-styling Example configuration for a dark-themed modal viewer. ```css storifyme-modal { --storify-modal-background: rgba(0, 0, 0, 0.95); --storify-modal-btn-background: #333333; --storify-modal-btn-arrow-fill: #ffffff; } ``` -------------------------------- ### GET /stories Source: https://docs.storifyme.com/ Retrieve a list of stories associated with your StorifyMe account. ```APIDOC ## GET /stories ### Description Use this endpoint to retrieve the list of stories available in your account. ### Method GET ### Endpoint /stories ``` -------------------------------- ### Initialize SDK via StorifyMeWidget Source: https://docs.storifyme.com/stories/react-native-sdk Direct initialization by passing credentials to the StorifyMeWidget component. ```javascript import { StorifyMeWidget, StorifyMeEnv } from 'react-native-storifyme'; export default function App() { return ( ); } ``` -------------------------------- ### UI Testing with XCUIApplication Source: https://docs.storifyme.com/stories/ios-sdk/ios-advanced-patterns Demonstrates verifying widget visibility and interaction using XCUIApplication with a specific launch argument. ```swift import XCTest class StoriesUITests: XCTestCase { private var app: XCUIApplication! override func setUp() { super.setUp() app = XCUIApplication() app.launchArguments.append("--uitesting") app.launch() } func testStoriesWidgetDisplays() { // Wait for stories widget to appear let storiesWidget = app.otherElements["StoriesWidget"] XCTAssertTrue(storiesWidget.waitForExistence(timeout: 10)) } func testStoryOpensOnTap() { // Given let storiesWidget = app.otherElements["StoriesWidget"] XCTAssertTrue(storiesWidget.waitForExistence(timeout: 10)) // When storiesWidget.tap() // Then let storyViewer = app.otherElements["StoryViewer"] XCTAssertTrue(storyViewer.waitForExistence(timeout: 5)) } } ``` -------------------------------- ### Manually Initialize or Update SDK Source: https://docs.storifyme.com/snaps/web-sdk Call the init method to initialize the SDK or update configuration parameters like Account ID and API Key at runtime. ```html ``` ```javascript // Get the widget element const snapsSdk = document.querySelector('storifyme-snaps-sdk'); // Set/Change the Snaps initialization parameters snapsSdk.init({ account: '', apiKey: '', env: '', }); ``` -------------------------------- ### GET Server Segments Source: https://docs.storifyme.com/stories/ios-sdk/ios-segmentation Retrieves the segments configured on the server for the loaded widget. ```APIDOC ## GET Server Segments ### Description Retrieves an array of segment tags defined in the StorifyMe platform editor for the specific widget. This should be called after the widget has successfully loaded. ### Response - **serverSegments** (Array) - List of tags configured on the server. ### Response Example ```swift let serverSegments = storifyMeWidget.getServerSegments() // Returns: ["featured", "sport"] ``` ``` -------------------------------- ### Get Widget Properties Source: https://docs.storifyme.com/stories/android-sdk/android-configuration Retrieve story thumbnail size and other UI properties. ```kotlin storiesView.getWidgetProperties() ``` -------------------------------- ### Advanced Link Handling with onAction and onLinkOpenTriggered Source: https://docs.storifyme.com/stories/android-sdk/android-events This example shows how to use both `onAction` to capture link details (like type and value) and `onLinkOpenTriggered` to conditionally control link opening based on these details. It also demonstrates resetting captured values. ```kotlin private var elementType: String? = null private var buttonValue: String? = null StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onAction(type: String, data: JSONObject?) { // Extract "data" object val buttonData = data.optJSONObject("data") // Extract button value buttonValue = buttonData?.optString("value", "") // Extract the element type (e.g., BUTTON, PRODUCT_TAG, etc.) elementType = data.optString("type", "") } override fun onLinkOpenTriggered( url: String, completion: (StorifyMeLinkTriggerCompletion) -> Unit ) { // This condition is just an example. You can replace it with any other condition that fits your use case. // For example: // val checkSomeCondition = url.contains("example.com") // A condition to check if the URL contains "example.com" // Check if the element type is "BUTTON" and if the button's value matches the URL. val checkSomeCondition = (elementType == "BUTTON" && buttonValue == url) // Example condition, can be replaced with your own logic if (checkSomeCondition) { // Prevent opening the link and handle manual link opening completion(StorifyMeLinkTriggerCompletion.IGNORE_PRESENTING_LINK) } else { // Proceed with the default link handling completion(StorifyMeLinkTriggerCompletion.OPEN_LINK_BY_DEFAULT) } // Reset values after handling the link open trigger // This ensures the elementType and buttonValue are cleared for the next event or action. elementType = null buttonValue = null } } ``` -------------------------------- ### Get Server Segments Source: https://docs.storifyme.com/stories/android-sdk/android-segmentation Retrieves the segments configured for the widget on the StorifyMe server. ```APIDOC ## getServerSegments ### Description Returns an array of segment tags defined in the StorifyMe platform editor for the specific widget. ### Response - **serverSegments** (Array) - The list of tags configured on the server. ### Response Example ```kotlin val serverSegments = storiesView.getServerSegments() ``` ``` -------------------------------- ### GET /widgets Source: https://docs.storifyme.com/ Retrieve details of a specific widget for custom integration purposes. ```APIDOC ## GET /widgets ### Description Get the details of the widget to enable custom integration within your application. ### Method GET ### Endpoint /widgets ``` -------------------------------- ### Disable Initial Onboarding Source: https://docs.storifyme.com/stories/ios-sdk/ios-configuration Hide or permanently disable the initial onboarding tutorial. ```swift StorifyMe.instance.disableInitialOnboarding() ``` ```swift StorifyMeInstance.shared.disableInitialOnboarding() ``` -------------------------------- ### Compact Additional Stories Styling Source: https://docs.storifyme.com/stories/web-sdk/single-item-embed/web-styling Example configuration for a more compact layout of additional stories. ```css storifyme-story { --storify-item-gap: 20px; --storify-item-radius: 12px; --storify-item-title-size: 0.9rem; } ``` -------------------------------- ### Initialize SDK Environment Source: https://docs.storifyme.com/stories/android-sdk/android-troubleshooting Switch between development and production environments during SDK initialization. ```kotlin // Switch between development and production StorifyMe.instance.initalize( accountId = "dev-account-id", // Use dev account for testing apiKey = "dev-api-key", environment = StorifyMeEnvironment.DEVELOPMENT // If available ) ``` -------------------------------- ### Remove isInEditMode() Example Source: https://docs.storifyme.com/stories/android-sdk/release-notes Demonstrates the removal of the `isInEditMode()` method, simplifying widget configuration. ```dart Removing isInEditMode() with example configuration ``` -------------------------------- ### Initialize StorifyMe with Custom Base URL on Android Source: https://docs.storifyme.com/guides/advanced-integration/custom-base-url-and-pinning Configure the SDK during application startup. The environment must still be specified for crash analytics reporting. ```kotlin import com.storify.android_sdk.StorifyMe import com.storify.android_sdk.StorifyMeEnv class MyApplication : Application() { override fun onCreate() { super.onCreate() StorifyMe.init( context = this, apiKey = "your-api-key", accountId = "your-account-id", environment = StorifyMeEnv.EU, // Still required for analytics customBaseUrl = "https://stories.yourapp.com/" ) } } ``` -------------------------------- ### Disable Onboarding and Tutorial Source: https://docs.storifyme.com/stories/android-sdk/android-configuration Prevents the initial onboarding or tutorial screens from appearing. ```kotlin StorifyMe.instance.disableInitialOnboarding() ``` ```kotlin StorifyMe.instance.disableInitialOnboarding() ``` -------------------------------- ### Webhook Payload Example Source: https://docs.storifyme.com/guides/self-hosting This is the structure of the payload received when a story is exported via webhook. ```json { "id": "st-ev-1", "type": "story.exported", "created": 1617024965948, "data": { "id": 1, "file": "story_export_file.zip", "downloadLink": "https://storifyme.com/api/exports/export/download?name=story_export_file.zip&token=one_time_auth_token" } } ``` -------------------------------- ### Initialize StorifyMe SDK with Callback Source: https://docs.storifyme.com/stories/ios-sdk Initializes the StorifyMe SDK and handles the completion result using a callback to determine success or failure. ```swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { StorifyMeInstance.shared.initialize( accountId: "ACCOUNT_ID", apiKey: "API_KEY", env: .EU ) { result in switch result { case .success: print("StorifyMe SDK is ready") case .failure(let error): print("StorifyMe SDK failed to initialize: \(error.message)") } } return true } ``` -------------------------------- ### Get Widget Properties Source: https://docs.storifyme.com/stories/android-sdk/android-configuration Retrieves the current story thumbnail size and other UI properties. ```APIDOC ## GET storiesView.getWidgetProperties() ### Description Retrieve story thumbnail size and other UI properties. ### Method GET ### Endpoint storiesView.getWidgetProperties() ``` -------------------------------- ### Apply brand color overrides Source: https://docs.storifyme.com/stories/web-sdk/web-setup-widget Example of overriding multiple variables to match brand colors. ```css story-widget { --storify-title-color: #2c3e50; --storify-carousel-btn-background: #3498db; --storify-carousel-btn-arrow-fill: white; --storify-item-live-background: #e74c3c; } ``` -------------------------------- ### Implement Preloading Strategy Source: https://docs.storifyme.com/stories/android-sdk/android-performance Pre-fetch story data in the background using an invisible view to reduce perceived latency when the user navigates to the content. ```kotlin class StoriesPreloader { private val preloadedWidgets = mutableMapOf>() fun preloadWidget(widgetId: Long) { if (preloadedWidgets.containsKey(widgetId)) return // Create invisible view for preloading val context = MyApplication.instance val preloadView = StoriesView(context) StorifyMe.instance.eventListener = object : StorifyMeEventListener() { override fun onLoad(widgetId: Long, stories: List) { preloadedWidgets[widgetId] = stories // Clean up preload view } override fun onFail(widgetId: Long, error: String) { Log.w("Preloader", "Failed to preload widget $widgetId: $error") } } preloadView.widgetId = widgetId preloadView.load() } fun isPreloaded(widgetId: Long): Boolean { return preloadedWidgets.containsKey(widgetId) } } ``` -------------------------------- ### Initialize StorifyMe with Custom Base URL on iOS Source: https://docs.storifyme.com/guides/advanced-integration/custom-base-url-and-pinning Use the shared instance to initialize the SDK in the application delegate. Certificate pins can be passed as nil if not currently configured. ```swift import StorifyMe func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { StorifyMeInstance.shared.initialize( accountId: "your-account-id", apiKey: "your-api-key", env: .EU, // Still required for analytics customBaseUrl: "https://stories.yourapp.com/", certificatePins: nil ) return true } ```