Annex

  1. Overview of all VisxAdViewDelegates
  2. Overview of all Closures
  3. Setting Keyword Targeting
  4. Setting Advertising Label (Banner only)
  5. Disable Resizing (Banner only)
  6. Header Bidding, Lazy Loading
Overview of all VisxAdViewDelegates

The following VisxAdViewDelegate delegate can be used for both banner and interstitial placements. You can use them for adding logic from your app between ad calls, ad rendering and disposal.

public protocol VisxAdViewDelegate {
    // Required methods
    /// ViewController for presenting VisxAdView
    func viewControllerForPresentingVisxAdView() -> UIViewController
    /// The SDK has initiated the WebView and successfully injected the creative content, including the OM SDK and mraid.js.
    /// The AdView / WebView is now ready to be added as a sub view.
    func visxAdViewDidInitialize(visxAdView: VisxAdView, effect: VisxPlacementEffect)
    // Optional methods
    /// The SDK has initiated an ad request to the VIS.X® Platform
    optional func visxAdRequestStarted(visxAdView: VisxAdView)
    /// The SDK has received an ad response from the VIS.X® Platform
    /// Only available for Header Bidding integration
    /// Currency is represented as ISO-4217 Code (e.g. "EUR")
    optional func visxAdResponseReceived(visxAdView: VisxAdView, price: Decimal, currency: String)
    /// Requesting, retrieving or rendering of an ad has failed, e.g. there is no ad to display, connection issues, bad configuration, internal errors
    /// Mediation has failed, e.g. due to no ad or missing adapter
    /// See error code and message for details, ad placement may be closed
    optional func visxAdFailedWithError(visxAdView: VisxAdView, message: String, code: Int)
    /// Ad creative has requested a size change for VisxAdView with a new width and height, please adjust accordingly
    optional func visxAdViewSizeChange(visxAdView: VisxAdView, width: CGFloat, height: CGFloat)
    /// Ad creative has changed its ad format type, e.g. from banner to YOC Understitial Ad®
    optional func visxAdViewEffectChange(visxAdView: VisxAdView, effect: VisxPlacementEffect)
    /// VisxAdView has been closed, ad placement may be closed
    optional func visxAdViewClosed(visxAdView: VisxAdView)
    /// Creative has been clicked
    optional func visxAdViewClicked(visxAdView: VisxAdView)
     /// Creative will open landing page in browser
    optional func visxLandingPageOpened()
    /// Interaction with banner creative is drawing focus from the app, e.g. by opening a modal view, or external browser
    optional func appShouldSuspendForAd(visxAdView: VisxAdView)
    /// Banner creative has opened a Modal View (e.g. in-app browser, pop-up), which is now closed
    optional func appShouldResumeFromAd(visxAdView: VisxAdView)
    /// Video creative has finished playing a video
    optional func visxAdVideoFinished(visxAdView: VisxAdView)
    /// Interstitial is about to be closed
    optional func visxAdInterstitialWillBeClosed(visxAdView: VisxAdView)
    /// Interstitial has been closed
    optional func visxAdInterstitialClosed(visxAdView: VisxAdView)
    /// A partial overlay (sticky) will open
    optional func visxAdStickyOpened(visxAdView: VisxAdView)
    /// A partial overlay (sticky) will be closed
    optional func visxAdStickyWillBeClosed(visxAdView: VisxAdView)
    /// A partial overlay (sticky) has been closed
    optional func visxAdStickyClosed(visxAdView: VisxAdView)
}
Overview of all VisxAdViewDelegates

The following Closures can be used as callbacks for both banner and interstitial placements. You can use them for adding logic from your app between ad calls, ad rendering and disposal.

    /// The SDK has initiated the WebView and successfully injected the creative content, including the OM SDK and mraid.js.
    /// The AdView / WebView is now ready to be added as a sub view.
    public func onInitialize(_ callback: @escaping (VisxAdView, VisxPlacementEffect) -> Void) -> VisxAdCallbackHandler {
        initializeCallback = callback
        return self
    }
    /// Requesting, retrieving or rendering of an ad has failed, e.g. there is no ad to display, connection issues, bad configuration, internal errors
    /// Mediation has failed, e.g. due to no ad or missing adapter
    /// See error code and message for details, ad placement may be closed
    public func onError(_ callback: @escaping (VisxAdView, Error) -> Void) -> VisxAdCallbackHandler {
        errorCallback = callback
        return self
    }
    // Optional methods
    /// The SDK has initiated an ad request to the VIS.X® Platform
    public func onRequestStarted(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        requestStartedCallback = callback
        return self
    }
    /// The SDK has received an ad response from the VIS.X® Platform
    /// Only available for Header Bidding integration
    /// Currency is represented as ISO-4217 Code (e.g. "EUR")
    public func onResponseReceived(_ callback: @escaping (VisxAdView, Double, String) -> Void) -> VisxAdCallbackHandler {
        responseReceivedCallback = callback
        return self
    }
    /// Ad creative has requested a size change for VisxAdView with a new width and height, please adjust accordingly
    public func onSizeChange(_ callback: @escaping (VisxAdView, CGFloat, CGFloat) -> Void) -> VisxAdCallbackHandler {
        sizeChangeCallback = callback
        return self
    }
    /// Ad creative has changed its ad format type, e.g. from banner to YOC Understitial Ad®
    public func onEffectChange(_ callback: @escaping (VisxAdView, VisxPlacementEffect) -> Void) -> VisxAdCallbackHandler {
        effectChangeCallback = callback
        return self
    }
    /// VisxAdView has been closed, ad placement may be closed
    public func onClose(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        closeCallback = callback
        return self
    }
    /// Creative has been clicked
    public func onClick(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        clickCallback = callback
        return self
    }
    /// Creative will open landing page in browser
    public func onLandingPageOpen(_ callback: @escaping () -> Void) -> VisxAdCallbackHandler {
        landingPageOpenCallback? = callback
        return self
    }
    /// Interaction with banner creative is drawing focus from the app, e.g. by opening a modal view, or external browser
    public func onSuspend(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        suspendCallback = callback
        return self
    }
    /// Banner creative has opened a Modal View (e.g. in-app browser, pop-up), which is now closed
    public func onResume(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        resumeCallback = callback
        return self
    }
    /// Video creative has finished playing a video
    public func onVideoFinish(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        videoFinishCallback = callback
        return self
    }
    /// Interstitial is about to be closed
    public func onInterstitialWillClose(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        interstitialWillCloseCallback = callback
        return self
    }
    /// Interstitial has been closed
    public func onInterstitialDidClose(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        interstitialDidCloseCallback = callback
        return self
    }
    /// A partial overlay (sticky) will open
    public func onStickyOpen(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        stickyOpenCallback = callback
        return self
    }
    /// A partial overlay (sticky) will be closed
    public func onStickyWillClose(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        stickyWillCloseCallback = callback
        return self
    }
    /// A partial overlay (sticky) has been closed
    public func onStickyDidClose(_ callback: @escaping (VisxAdView) -> Void) -> VisxAdCallbackHandler {
        stickyCloseCallback = callback
        return self
    }
Setting Keyword Targeting

The VIS.X® SDK for SwiftUI allows the setting of individual key-value targeting for placements. This can be useful, among other things, if contextually different blocklists or floor prices are used for one ad unit (e.g., channel targeting).

For these targetings to be effective, an individual agreement with the account manager is necessary so that they can also be implemented on the YOC backend configuration.

adView = VisxAdView(adUnit: "123456", 
                           adViewDelegate: self, 
                           adSize: CGSize(width: 300, height: 250), 
						   interstitial: Bool? = false)

let inAppKeyTargetingDict = ["age" :"20-30,30-50",
                              "sport-cars":"Porsche,Audi",
                              "channel":"Finance"]
adView.loadWithCustomTargetingParameters(inAppKeyTargetingDict)
adView.load()
Parameter Description
VisxAdView.loadWithCustomTargetingParameters(params: [String : String]) .loadWithCustomTargetingParameters() allows you to setup additional key-value targeting for your placement.

The following constraints apply when using custom key-value targeting:

For Keys:

  • Keys must consist of [\w_-\d] Unicode word characters, incl. [0-9_-]
  • Up to 5 keys are accepted in a single ad call
  • Keys are OR combined
  • Keys must have at least one value. Pure key targeting is not accepted
  • Keys must not use breakable and non-breakable spaces

For Values:

  • Values must consist of [\w_-\d] Unicode word characters, incl. [0-9_-]
  • Multiple values are accepted, they need to be comma-separated
  • Values are OR combined
  • Values must not use breakable and non-breakable spaces
  • Values associated with a key will be overridden if the key is pushed again

Setting Advertisement Label (Banner only)

The EU Directive 2000/31/EC declares “[..] commercial communication shall be identified as such”. Non-EU countries may also require similar identifiability of advertising. Advertising should be labeled and visually separated from editorial content. You can use adView.advertisingLabelText() before you call adView.load() to apply a label on top of the creative, in all cases, YOC is delivering an ad. The String could be either plain text, e.g. "Advertisement"; or escaped HTML, e.g. "<span style=\"font-size:12px\">Werbung</span>".

Method (optional) Description
VisxAdView.advertisingLabelText(String) Call .advertisingLabelText() before .load() with either plain text, or escaped html to set an advertisement label above the creative.
Disable Resizing (Banner only)

To play high-impact ad formats from YOC, VIS.X ad units must be able to adjust the size of the adContainer by default. However, there are positions in the app where this is simply not possible. In this case, the resizing can be restricted by initializing the VisxAdView with the fixedSize set to true. As it will heavily affect monetization, it is advised to use this init method only if needed and report usage to your YOC account manager, to remove high-impact ads for that ad unit.

private var adView: VisxAdView?
// ..
adView = VisxAdView(adUnit: adId, adViewDelegate: self, adSize: adSize, fixedSize: true)
Header Bidding, Lazy Loading

The default life cycle of ads in the SDK is split into two steps:

  1. The app requests an ad, VIS.X® will respond with an ad and prepare the ad to be displayed, by creating a WebView immediately
  2. The app will listen to visxAdViewDidInitialize, pick up the VisxAdView and add it as a SubView into the ViewHierachy

This workflow is based on the assumption that the publisher asks for an ad whenever they need one. However, there are also scenarios where the app wants to ask an ad, but not necessarily render them, e.g. in a header bidding scenario or when prefetching ads is performed to increase the overall speed of the app.

For this kind of scenario, the VIS.X® SDK can split the delivery into three steps:

  1. The app requests an ad, VIS.X® will respond with an ad and call visxAdResponseReceived with a Price and a Currency
  2. The app decides to initiate the render process by calling renderAd method, initiating the WebView
  3. The app will listen to visxAdViewDidInitialize, pick up the VisxAdView and add it as a SubView into the ViewHierachy

To enable this feature use the header bidding initializer and conform to the VisxHeaderBiddingDelegate, which is a subset of VisxAdViewDelegate

public convenience init(adUnit: String,
                        headerBiddingDelegate: VisxHeaderBiddingDelegate,
                        adSize: CGSize,
                        fixedSize: Bool = false,
                        interstitial: Bool = false)

In the visxAdResponseReceived delegate method, you can call renderAd to resume the rendering process.

    func visxAdResponseReceived(visxAdView: VisxAdView, price: Decimal, currency: String) {
        // ad is received and ready to be rendered as a webView
        if price > 0.001 {
            visxAdView.renderAd()
            // when the ad is finally rendered visxAdViewDidInitialize is called
        }
    }