Skip to content

StorytellerModule#

The StorytellerModule module is a protocol you can adopt to handle fetching ads and recording user activity events from Storyteller.

Properties#

adSource#

adSource: StorytellerAdSource? identifies the ad source for ads provided by your module.

  • Use .custom("myNetwork") for a custom integrating-app source.
  • Use .gam for Google Ad Manager and .admob for Google AdMob.
  • The SDK-provided VAST module uses .custom("vast").
  • .storyteller is reserved for Storyteller First Party ads.
  • Return nil when no source should be attached.

This value is attached to ad analytics payloads when available.

If not implemented, the default value is nil.

The SDK-provided StorytellerGAMModule, StorytellerAdMobModule, and StorytellerVASTModule set this value automatically.

See how the Showcase app registers modules in AppDelegate.setupStoryteller.

Methods#

Analytics#

The callback onUserActivityOccurred provides analytics events and corresponding data triggered internally by the SDK. This information can be used in your app.

The following parameters are passed to the callback method:

  • type - type of event that occurred, as a StorytellerUserActivity.EventType enum
  • data - an object containing data about the event which occurred

Example:

func onUserActivityOccurred(type: StorytellerUserActivity.EventType, data: StorytellerUserActivityData) {
    if type == .OpenedStory {
        // Retrieve the story id value
        let openedStoryId = data.storyId
        // Retrieve the story title value
        let openedStoryTitle = data.storyTitle

        // Report retrieved values from your app
    }
}

For a detailed discussion of all the relevant events and properties please see the dedicated Analytics page.

Ads#

By implementing getAd and getBottomBannerAd, you can provide custom ad data for the SDK to render. This is only applicable when the ad configuration is set to Integrating App in the CMS. Ad data can be obtained asynchronously using async/await, and should be returned directly or throw an error if no ad is available.

When building ad CTAs, StorytellerAdAction supports StorytellerActionType.web, StorytellerActionType.inApp, StorytellerActionType.externalApp, and StorytellerActionType.store.

getAd#

The getAd method is called when the SDK needs a fullscreen ad:

final class CustomAdsModule: StorytellerModule {
    enum AdLoadingError: Error {
        case unavailable
    }

    let loadAd: () async -> StorytellerAd?

    init(loadAd: @escaping () async -> StorytellerAd?) {
        self.loadAd = loadAd
    }

    func getAd(for adRequestInfo: StorytellerAdRequestInfo) async throws -> StorytellerAd {
        guard let ad = await loadAd() else {
            throw AdLoadingError.unavailable
        }
        return ad
    }
}

Bottom Banner Ads#

The getBottomBannerAd method is called when the SDK needs a bottom banner ad (displayed at the bottom of clips). The maxHeight parameter indicates the maximum allowed banner height for the current layout:

final class CustomBannerAdsModule: StorytellerModule {
    enum AdLoadingError: Error {
        case unavailable
    }

    let loadBannerAd: (CGFloat) async -> StorytellerAd?

    init(loadBannerAd: @escaping (CGFloat) async -> StorytellerAd?) {
        self.loadBannerAd = loadBannerAd
    }

    func getBottomBannerAd(for adRequestInfo: StorytellerAdRequestInfo, maxHeight: CGFloat) async throws -> StorytellerAd {
        guard let ad = await loadBannerAd(maxHeight) else {
            throw AdLoadingError.unavailable
        }
        return ad
    }
}

Request-aware ad modules#

Host-provided GAM or AdMob modules that know the exact ad unit only when starting a provider request can adopt StorytellerAdRequestTrackingModule. Set adSource to .gam or .admob so the SDK emits paid operational events. The protocol extends StorytellerModule with request-aware full-screen and bottom-banner methods:

  • getAdWithRequestTracking(for:slot:onAdRequested:)
  • getBottomBannerAdWithRequestTracking(for:maxHeight:onAdRequested:)

Await onAdRequested immediately before each concrete provider load. Call it once for each native or banner attempt, including fallback attempts, invoke it serially, and do not retain it after the method returns. The SDK uses each reported value for Google AdRequested events and correlates the final attempt with load, failure, and paid events.

Set the same value on the returned StorytellerAd.adUnitId so rendered Ad lifecycle events retain it. The optional slot identifies the active full-screen request; modules that support cancelling their underlying load should honor its cancellation state. SDK-provided GAM and AdMob modules adopt this capability automatically.

For a detailed discussion of all the relevant considerations, please see the dedicated Ads page.

Technical Consideration#

Because the StorytellerDelegate also conforms to StorytellerModule, the way our SDK works is as following:

  • whenever ads are requested, each module has a chance to fetch modules, in the order they appear in the modules array. If a module throws an error, the next one will be queried. Lastly the delegate is requested to provide an ad. If all fail to return an ad, no ad is shown.
  • whenever onUserActivityOccurred is called, all modules will process the event, in the same order, and lastly the delegate will do the same.