Configuration
If you're using CocoaPods, please migrate to Swift Package Manager. CocoaPods support will be removed by end of 2026. See Migration Guide.
Initialization
Initialize the SDK once, typically in AppDelegate or SceneDelegate:
StorifyMeInstance.shared.initialize(
accountId: "YOUR_ACCOUNT_ID",
apiKey: "YOUR_API_KEY",
env: .EU
)
Custom Gateway Request Headers
If your custom gateway requires an app-owned session header, register the request interceptor before
initializing the SDK. It runs synchronously for each stories, base-template, audience, and ads content
API request routed through customBaseUrl, so the app can provide a refreshed token on every request.
The callback receives the absolute request URL and current headers, including accountId; return the
complete header map to send.
StorifyMeSDK.requestInterceptor = { url, headers in
var requestHeaders = headers
requestHeaders["Authorization"] = "Bearer \(session.currentToken())"
return requestHeaders
}
StorifyMeSDK.initialize(
accountId: "YOUR_ACCOUNT_ID",
apiKey: "YOUR_API_KEY",
environment: .EU,
customBaseUrl: "https://gateway.example.com"
)
The interceptor only applies to content API requests using the configured custom base URL. It does not add headers to media or WebView traffic. The SDK does not store or log returned header values. If the callback throws, the request fails. Keep it synchronous and make sure the gateway does not redirect requests to a different origin; the SDK does not reapply headers after redirects.
Set StorifyMeSDK.requestInterceptor = nil to unregister the callback.
Adding a Widget
let widget = StorifyMeWidget()
widget.setWidgetId(widgetId: YOUR_WIDGET_ID)
widget.load()
view.addSubview(widget)
widget.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
widget.leadingAnchor.constraint(equalTo: view.leadingAnchor),
widget.trailingAnchor.constraint(equalTo: view.trailingAnchor),
widget.heightAnchor.constraint(equalToConstant: 120)
])
Widgets automatically wait for SDK initialization, so load() can be called at any point.
Widget Configuration
Playback Behavior
storifyMeWidget.setPlaybackOptions(
options: StorifyMeStoryPlaybackOptions(behaviour: .restartStoriesOnAppLaunch)
)
| Option | Behavior |
|---|---|
alwaysResumeStoryWhereStopped | Resume where the user stopped (default) |
restartStoriesOnAppLaunch | Restart on every app launch |
restartStoriesWhenOpen | Restart every time the widget is opened |
Audio Control
storifyMeWidget.setWidgetAudioOptions(
options: StorifyMeStoryAudioOptions(
behaviour: .applyLastUserChangeForAllFutureStories,
defaultState: .unmuted
)
)
| Option | Behavior |
|---|---|
applyLastUserChangeForAllFutureStories | Remembers user's last audio choice (default) |
applyChangeForSingleStory | Audio state resets for each story |
applyChangeForPresentedStories | Audio state resets after widget is dismissed |
Poster Thumbnails
storifyMeWidget.setGifPosterEnabled(true) // GIF posters — enabled by default
storifyMeWidget.setVideoPosterEnabled(true) // Video posters — disabled by default
URL Presentation
storifyMeWidget.setURLPresentationOptions(
options: StorifyMeURLPresentationOptions(presentationMode: .inAppBrowser)
)
.externalBrowser— open in Safari (default).inAppBrowser— open in-app
Direction and Language
var config = StorifyMeWidgetConfig()
config.setDirection(direction: .rtl)
config.setLanguage(languageCode: "en")
storifyMeWidget.setWidgetConfig(config: config)
Scroll Navigation
storifyMeWidget.setWidgetScrollNavigationOptions(
options: StorifyMeWidgetScrollNavigationOptions(storiesNavigation: .verticalCenteredControls)
)
Disable Onboarding
StorifyMeInstance.shared.disableInitialOnboarding()
Opening Stories Programmatically
Open a specific story from code — by position, handle, or ID:
storifyMeWidget.openWidgetStoryByPosition(0, storyBehaviour: nil) { result in }
storifyMeWidget.openWidgetStoryByHandle("my-story-handle", storyBehaviour: nil) { result in }
storifyMeWidget.openWidgetStoryById(42, storyBehaviour: nil) { result in }
To open a story without a widget (e.g. from a deep link or push notification):
StorifyMeInstance.shared.openStoryByHandle(handle: "my-story-handle")
Story IDs, handles, and count are available in the onLoad event callback.
Utility Methods
Playback Control
StorifyMeInstance.shared.playbackController.pausePlayback(controlsVisibility: .visible)
StorifyMeInstance.shared.playbackController.resumePlayback(mode: .fromBeginning)
StorifyMeInstance.shared.playbackController.closePlayback()
Clear Seen State
storifyMeWidget.clearAllSeenState() // Clear all, refresh list
storifyMeWidget.clearSeenState(storyId: 42) // Clear one story
In-Story Notifications
StorifyMeInstance.shared.showNotification(title: "Title", message: "Message")
Logging
Set the log level before initialize() to capture initialization logs:
StorifyMeInstance.shared.logLevel = .debug
| Level | Description |
|---|---|
.debug | Development debugging |
.warning | Recoverable problems (default) |
.error | Critical errors only |
.none | Recommended for production |
Logs appear in Xcode Console and Console.app (filter by subsystem com.storifyme.sdk).
GIF Cache
StorifyMeInstance.shared.diskCacheMaxAge = 7 * 24 * 60 * 60 // 7 days (default)
StorifyMeInstance.shared.clearAllGIFCaches() // Manual clear
For SwiftUI:
StorifyMeWidgetView.clearAllCaches()
SDK Lifecycle
For lifecycle management — SDK state observation, whenReady, shutdown, account switching, and notification-based patterns — see Advanced Integration Patterns.