Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added iOS Prebid Plugin Renderer #5580

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions _data/sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,14 @@
sectionTitle:
subgroup: 2

- sbSecId: 2
title: Prebid Plugin Renderer
link: /prebid-mobile/pbm-api/ios/pbm-plugin-renderer.html
isHeader: 0
isSectionHeader: 0
sectionTitle:
subgroup: 2

- sbSecId: 2
title: "For Android"
link:
Expand Down
189 changes: 189 additions & 0 deletions prebid-mobile/pbm-api/ios/pbm-plugin-renderer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
---
layout: page_v2
title: Plugin Renderer - iOS
description: Guide to implement a Plugin Renderer
top_nav_section: prebid-mobile
nav_section: prebid-mobile
sidebarType: 2
---

# Prebid Plugin Renderer
{:.no_toc}

* TOC
{:toc}

## Overview
Plugin Renderer is a feature that enables the ability to delegate the ad rendering to a component of yours. Such feature turn possible, for instance, the rendering of non-standard ad responses that Prebid Mobile SDK can not render by itself. This integration require from you, in first place, to have a Bidder Adapter implemented in order to handle bid requests from the Prebid Mobile SDK that include your Plugin Renderer.

![Plugin Renderer big picture](/assets/images/prebid-mobile/prebid-plugin-renderer.png)

### Ad view transposing

Everytime that a bid response is received and it reaches the rendering stage, Prebid SDK will delegate the ad view rendering to an existing Plugin Renderer, such as a custom one if this is elected or the default one in any other case.

Take the example on the image below where a BannerView will have its ad view transposed accordingly to the Plugin Renderer status. The inner ad view is handled totally under the hood from the app owner point of view, what makes unnecessary any change on the BannerView loading or initialization.

{: .alert.alert-info :}
In case of Interstitial ad this is just inflated in the foreground regardless the view hierarchy.

![Plugin Renderer big picture](/assets/images/prebid-mobile/prebid-plugin-renderer-ad-view-injection.png)

### Setup

* Provide your Prebid Bidder Adapter
* [Go integration](/prebid-server/developers/add-new-bidder-go.html)
* [Java integration](/prebid-server/developers/add-new-bidder-java.html)
* Create your implementation from the interface `PrebidMobilePluginRenderer`
* Initialise your Plugin Renderer before starting to request ads
* Take advantage of the Plugin Renderer fields

{: .alert.alert-info :}
Please notice that all implementation on mobile related to the Plugin Renderer should be provided externally, not in the PBM SDK itself. For instance, an app owner or third party SDK would implement it and initialise it on their own context.

___

#### Create your implementation from the interface PrebidMobilePluginRenderer

```swift
public class SampleCustomRenderer: NSObject, PrebidMobilePluginRenderer {

public let name = "SampleCustomRenderer"

public let version = "1.0.0"

public var data: [AnyHashable: Any]? = nil

private var adViewManager: PBMAdViewManager?

public func isSupportRendering(for format: AdFormat?) -> Bool {}

public func setupBid(_ bid: Bid, adConfiguration: AdUnitConfig, connection: PrebidServerConnectionProtocol) {}

public func createBannerAdView(with frame: CGRect, bid: Bid, adConfiguration: AdUnitConfig,
connection: PrebidServerConnectionProtocol, adViewDelegate: (any PBMAdViewDelegate)?) {
// TODO "Handle bid response as you want and display your banner ad"
}

public func createInterstitialController(bid: Bid, adConfiguration: AdUnitConfig, connection: PrebidServerConnectionProtocol,
adViewManagerDelegate adViewDelegate: InterstitialController?, videoControlsConfig: VideoControlsConfiguration?) {
// TODO "Handle bid response as you want and display your interstitial ad"
}
}

```

#### Initialise your Plugin Renderer before starting to request ads and unregister your plugin once it is done

```swift
class CustomRendererBannerController: NSObject, AdaptedController, PrebidConfigurableBannerController, BannerViewDelegate {

required init(rootController: AdapterViewController) {
super.init()
self.rootController = rootController
Prebid.registerPluginRenderer(sampleCustomRenderer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to register the plugin during the application launch step right after the Prebid SDK initialization? In this case, publishers will not have to register the plugin in each needed place in the app.

setupAdapterController()
}

deinit {
Prebid.unregisterPluginRenderer(sampleCustomRenderer)
}
}
```

## Limitations

### Supported Ad Formats
Currently the interface `PrebidMobilePluginRenderer` provide the ability to render `BANNER` and `INTERSTITIAL` only. The compability with more ad formats can be supported in future releases.

It is important to notice that the compliant formats you set on `isSupportRenderingFor` implementation are taken into account to add your Plugin Renderer to the bid request or not, according to the ad unit configuration that is bid requesting.

### Original API

The Plugin Renderer feature does not work with [GAM Original API](/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.html) since the ad rendering does not happen in the Prebid SDK but externally. Despite that if you are using the regular GAM integration it will work fine.

## Ad Event Listeners
An optional dedicated generic ad event listener is offered in case of the existing event listeners are insufficient to keep your ad consumer fully aware of your ad lifecycle.

![Plugin Event Listener big picture](/assets/images/prebid-mobile/prebid-plugin-renderer-event-listeners.png)

### Setup

* Create your implementation from the interface `PluginEventDelegate`
* Handle your plugin event listener on your Plugin Renderer
* Implement the interface on the class you want to listen the events
* Set your listener on your `BannerView` instance or `InterstitialAdUnit` instance

___

#### Create your implementation from the interface PluginEventDelegate

```swift
@objc class SampleCustomRendererEventDelegate: NSObject, PluginEventDelegate {
func getPluginName() -> String {
return "SamplePluginRenderer"
}

func onImpression() {
// TODO on impressions
}
}

```

#### Handle your plugin event delegate on your Plugin Renderer

```swift
public class SampleCustomRenderer: NSObject, PrebidMobilePluginRenderer {

// Store your listeners
private var pluginEventDelegateMap = [String: SampleCustomRendererEventDelegate]()

public let name = "SampleCustomRenderer"

public let version = "1.0.0"

public var data: [AnyHashable: Any]? = nil

private var adViewManager: PBMAdViewManager?

public func isSupportRendering(for format: AdFormat?) -> Bool {}

public func registerEventDelegate(pluginEventDelegate: any PluginEventDelegate, adUnitConfigFingerprint: String) {
pluginEventDelegateMap[adUnitConfigFingerprint] = pluginEventDelegate as? SampleCustomRendererEventDelegate
}

public func unregisterEventDelegate(pluginEventDelegate: any PluginEventDelegate, adUnitConfigFingerprint: String) {
pluginEventDelegateMap.removeValue(forKey: adUnitConfigFingerprint)
}

public func setupBid(_ bid: Bid, adConfiguration: AdUnitConfig, connection: PrebidServerConnectionProtocol) {}

public func createBannerAdView(with frame: CGRect, bid: Bid, adConfiguration: AdUnitConfig,
connection: PrebidServerConnectionProtocol, adViewDelegate: (any PBMAdViewDelegate)?) {
}

public func createInterstitialController(bid: Bid, adConfiguration: AdUnitConfig, connection: PrebidServerConnectionProtocol,
adViewManagerDelegate adViewDelegate: InterstitialController?, videoControlsConfig: VideoControlsConfiguration?) {
}
}
```

## Resources

In addition to this documentation you have samples on hand which can be get from the Prebid Mobile SDK repository:

* [PrebidMobilePluginRenderer](https://github.com/prebid/prebid-mobile-ios/blob/master/PrebidMobile/PrebidMobileRendering/PluginRenderer/PrebidMobilePluginRenderer.swift)
* [PluginEventDelegate](https://github.com/prebid/prebid-mobile-ios/blob/master/PrebidMobile/PrebidMobileRendering/PluginRenderer/PluginEventDelegate.swift)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PluginEventDelegate does not exist on master.

Current class name is still PluginEventListener

An update must to be added to prebid ios sdk

Copy link
Contributor

@github-lucas-bon github-lucas-bon Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, PR opened, this is not a block
prebid/prebid-mobile-ios#1046


___

## Plugin Renderer providers

The following list contains documentation for known supported Plugin Renderer providers.

{: .table .table-bordered .table-striped }

| Company | Documentation |
|-------|-----------------------------------------------------------------------------------------------|
<!-- | Teads | [Teads Plugin Renderer Docs](https://support.teads.tv/support/solutions/articles/36000459747) | -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review the renderd page. The table is broken on it.