Monetize the Conversation

Learn how the OpenWeb iOS SDK can monetize your Conversation.


The OpenWeb iOS SDK supports two ad formats:

  • Banner (320X50, 320x100, 300x250)
  • Interstitial (full page)

The interstitial ad appears once per article when the user navigates to a Conversation. The banner ad appears on the article page above the Conversation.



Requirements

  • Approved Google Ad Manager form for apps ads should indicate apps
  • An app-ads.txt file implemented in your web environment at www.your-domain.com/app-ads.txt


Implementation

Integrating the Google Mobile Ads SDK into your app sets the foundation for you to display ads and earn revenue. After adding and initiating the dependency, you must work with your OpenWeb PSM to set up the advertising campaign.

πŸ“˜

Since conflicts can occur when the Google Mobile Ads SDK is a dependency of both the host app and the OpenWeb iOS SDK, Google Mobile Ads SDK is not included as a direct dependency of the OpenWeb iOS SDK.

Enable ads

Use the following steps to support monetization with the OpenWeb iOS SDK:

  1. In a text editor, open Podfile.
  2. Add pod 'Google-Mobile-Ads-SDK', '8.0'.
target 'OpenWeb-SDK-iOS-Demo' do
  # Use one of those options
  use_frameworks!
  # use_frameworks! :linkage => :static

  # Pods for OpenWeb-SDK-iOS-Demo
  pod 'SpotIMCore'
  pod 'Google-Mobile-Ads-SDK', '8.0'
end
  1. In Terminal, at the terminal prompt of your project directory, execute pod install to install the dependency.
  2. In the app Info.plist, add a GADApplicationIdentifier key and a SKAdNetworkItems key:
    • Set the string value of the GADApplicationIdentifier key to your Ad Manager app ID.
    • Set the string value of the SKAdNetworkItems key to cstr6suwn9.skadnetwork.
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-***************~**********</string>
<key>SKAdNetworkItems</key>
  <array>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>cstr6suwn9.skadnetwork</string>
    </dict>
  </array>
  1. Add the GoogleAdsProvider.swift file to your project.
import UIKit
import GoogleMobileAds
import SpotImCore

final class GoogleAdsProvider: NSObject, AdsProvider {
    weak var bannerDelegate: AdsProviderBannerDelegate?
    weak var interstitialDelegate: AdsProviderInterstitialDelegate?

    private var banner: GAMBannerView?
    private var interstitial: GAMInterstitialAd?
    private var spotId: String = ""

    override init() {
        super.init()
    }

    func version() -> String { return "1.0" }

    func setSpotId(spotId: String) {
        self.spotId = spotId
    }

    func setupAdsBanner(with adId: String = Configuration.testBannerID, in controller: UIViewController, validSizes: Set<AdSize>) {
        var sizes: [NSValue] = validSizes.map { (size) -> NSValue in
            let gadSize = parseAdSizeToGADAdSize(adSize: size)
            return NSValueFromGADAdSize(gadSize)
        }

        if sizes.isEmpty {
            let defaultSize = parseAdSizeToGADAdSize(adSize: .small)
            sizes.append(NSValueFromGADAdSize(defaultSize))
        }

        banner = GAMBannerView()
        banner?.validAdSizes = sizes
        banner?.adUnitID = adId
        banner?.delegate = self
        banner?.rootViewController = controller
        let req = GAMRequest()
        req.customTargeting = ["bannerConvSdkSpotId":spotId]
        banner?.load(req)
    }

    func setupInterstitial(with adId: String = Configuration.testInterstitialID) {
        let req = GAMRequest()
        req.customTargeting = ["interConvSdkSpotId":spotId]

        GAMInterstitialAd.load(withAdManagerAdUnitID: adId, request: req) { ad, error in
            if let error = error {
                self.interstitialDelegate?.interstitialFailedToLoad(error: error)
                return
            }
            self.interstitial = ad
            self.interstitial?.fullScreenContentDelegate = self
            self.interstitialDelegate?.interstitialLoaded()
        }
    }

    func showInterstitial(in controller: UIViewController) -> Bool {
        guard let interstitial = interstitial else { return false }

        interstitial.present(fromRootViewController: controller)

        return true
    }

    private func parseAdSizeToGADAdSize(adSize: AdSize) -> GADAdSize {
        switch adSize {
        case .small:
            return kGADAdSizeBanner
        case .medium:
            return kGADAdSizeLargeBanner
        case .large:
            return kGADAdSizeMediumRectangle
        }
    }

    @objc public class func setSpotImSDKWithProvider() {
        SpotIm.setGoogleAdsProvider(googleAdsProvider: GoogleAdsProvider())
    }
}

extension GoogleAdsProvider: GADFullScreenContentDelegate {
    func adDidPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        interstitialDelegate?.interstitialWillBeShown()
    }

    func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
        interstitialDelegate?.interstitialDidDismiss()
    }

    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        interstitialDelegate?.interstitialDidDismiss()
    }
}

extension GoogleAdsProvider: GADBannerViewDelegate {

    func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
        bannerDelegate?.bannerLoaded(bannerView: bannerView, adBannerSize: bannerView.adSize.size, adUnitID: bannerView.adUnitID ?? "")
    }

    func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
        bannerDelegate?.bannerFailedToLoad(error: error)
    }
}

private extension GoogleAdsProvider {

    private enum Configuration {
        static let testInterstitialID: String = "/6499/example/interstitial"
        static let testBannerID: String = "/6499/example/banner"
    }
}
  1. Immediately after SpotIm.initialize(spotId: spotId), call setGoogleAdsProvider to set the Google ads provider to the SpotIm class.
SpotIm.setGoogleAdsProvider(googleAdsProvider: GoogleAdsProvider())

Disable ads

By default, OpenWeb helps you to monetize your content and engagement experiences by showing ads to your users.

If you would like to provide an ad-free experience for your subscribed users, use the following steps:

When you pass Base64-encoded "user_metadata.is_subscriber": true during the login process, you indicate that the user is a subscriber. During the user's session, no ads will be shown.

🚧

If a user's subscriber status changes, your app must log out the user and complete a new [SSO flow](http://google.com. This ensures that a user's previous cached client state for user_metadata.is_subscriber is not used.