-
Notifications
You must be signed in to change notification settings - Fork 93
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
Third party rendering #697
Comments
I made a full proposal on Android repository : prebid/prebid-mobile-android#507 |
In addition to the android proposal we add some implementations details on iOS side. ThirdPartyCustomRenderer: a new protocol for the third-party rendererFor doing third-party rendering, SDKs will have to implement a protocol specially created for it: @objc public protocol ThirdPartyCustomRenderer: NSObjectProtocol {
/// Call this to setup the renderer and register it as "third party renderer"
@objc static func setup()
@objc init()
@objc func loadAd(with frame: CGRect, bid: PrebidMobile.Bid, configId: String, adViewDelegate: PBMAdViewDelegate?)
} An important point of this protocol is the public typealias PBMAdViewDelegate = PBMThirdPartyAdViewLoader & PBMAdViewManagerDelegate Extend DisplayViewLoadingDelegate protocolWe need to extend @objc public protocol DisplayViewLoadingDelegate: NSObjectProtocol {
func displayViewDidLoadAd(_ displayView: PBMDisplayView)
func displayView(_ displayView: PBMDisplayView,
didFailWithError error: Error)
+ func customRenderDisplayViewDidLoadAd(_ displayView: UIView, adSize: CGSize)
} Updates to be done inside the PBMDisplayViewTo make it works we need to conform to the new protocol
That will just passed the view to the next delegate (DisplayViewLoadingDelegate). Display a custom ad when it is neededWe choose to put the call of the third-party renderer logic inside the function - (void)displayAd {
if (self.transactionFactory) {
return;
}
self.adConfiguration.adConfiguration.winningBidAdFormat = self.bid.adFormat;
+ if ([self loadThirdPartyRendererIfNeeded]) {
+ return;
+ }
@weakify(self);
self.transactionFactory = [[PBMTransactionFactory alloc] initWithBid:self.bid
adConfiguration:self.adConfiguration
}];
} This new function will return a boolean that will be false if no custom renderers were found. - (BOOL)loadThirdPartyRendererIfNeeded {
NSString *bidderClass = [[self.bid targetingInfo] valueForKey:@"hb_bidder"];
self.customRenderer = [self customRendererWithClassName:bidderClass];
if (self.customRenderer != nil) {
CGRect const displayFrame = CGRectMake(0, 0, self.bid.size.width, self.bid.size.height);
[self.customRenderer loadAdWith: displayFrame bid:self.bid configId: [_adConfiguration configId] adViewDelegate:self];
return YES;
}
return NO;
}
- (nullable id<ThirdPartyCustomRenderer>) customRendererWithClassName:(NSString *) className {
Class customRenderer = NSClassFromString(className);
return [[customRenderer alloc] init];
}
Use a singleton to stock the customs renderersAlternatively: we can use a singleton instead of loading the ThirdPartyCustomRenderer using NSClassFromString. We design a Singleton instance called @objc public class CustomRendererStore: NSObject {
@objc public static let shared = CustomRendererStore()
private override init() {
super.init()
}
public func addAdapter(_ adapter: ThirdPartyCustomRenderer, for key: String) {
adapters[key] = adapter
}
@objc public var adapters: [String: ThirdPartyCustomRenderer] = [String: ThirdPartyCustomRenderer]()
}
} On the loadThirdPartyRendererIfNeeded method, we just need to change the way we load the customRenderer. - (BOOL)loadThirdPartyRendererIfNeeded {
NSString *bidderClass = [[self.bid targetingInfo] valueForKey:@"hb_bidder"];
- self.customRenderer = [self customRendererWithClassName:bidderClass];
+ NSObject<CustomRenderer> *adapater = [[[CustomRendererStore shared] adapters] valueForKey: bidder];
if (self.customRenderer != nil) {
CGRect const displayFrame = CGRectMake(0, 0, self.bid.size.width, self.bid.size.height);
[self.customRenderer loadAdWith: displayFrame bid:self.bid configId: [_adConfiguration configId] adViewDelegate:self];
return YES;
}
return NO;
}
Also we need to make sure that the publisher will declare the custom renderer at some point before using it: CustomRendererStore.shared.addAdapter(TeadsPrebidAdapter(), for: "teads") |
Teads has finished the Android portion and it is already merged into the Android Repo. The iOS portion is to be handed off to myself and the committee/community to finish. |
Waiting for confirmation of docs PR. |
Antoine Barrault posted the next feature request in the Slack channel
Hello Prebid Mobile Team,
We would like to make a proposition about the development of a new feature we are going to make.
Context
We are planning of implement a third-party renderer feature (called as rendering delegation on prebid documentation). As part of this process, we need to pass an extra information inside the Bid Request in order to inform the Bid apdaters, that a custom renderer is available on the publisher app.
The information
The Bid adapter need to have a way to know if custom renderers are available in order to be able to deliver specials creatives. A simple representation for it, is an array of strings something like: [“custom_renderer_1”, “custom_renderer_2”].
We can call it third_party_renderers inside the openRTB representation.
Solution
To pass the information to the bid adpaters we can simply use the context data and passing a new key/value tuple.
Example:
A more robust alternative can be to implement a new global targeting parameter like User Keywords that will allow the publisher or third party SDKs to pass new strings (the supported custom renderers) to this object.
The text was updated successfully, but these errors were encountered: