larsacus / LARSAdController

Lightweight ad mediation for iOS to properly manage multiple ad networks dynamically including iAd and Google ads.
http://theonlylars.com/blog/2013/01/10/stupid-easy-ads-with-larsadcontroller-3-dot-0/
MIT License
269 stars 60 forks source link

Adapter ratio management #40

Open Fred10932 opened 11 years ago

Fred10932 commented 11 years ago

Most people who integrate the LARSAdController likely do so in order to use 2 or more adapters with it. I think it would be interesting to offer not only a primary/backup adapter model but also an adapter ratio based model. A very basic way to do this would be to increase e.g. an NSUserDefaults stored integer in the adapter's successful load delegate methods (e.g. adViewDidReceiveAd for AdMob or revmobAdDisplayed for RevMob). In the App delegate a simple check of the actual ratios versus desired ratios could then decide on which adapter is prioritized (e.g. something like if((adMobCount/(adMobCount + revMobCount + 1) <= 0.6) { register AdMob adapter first }else{ register RevMob adapter first}.

The idea would be of course to come to a cleaner way of doing this. e.g. by integrating it into an optional LarsAdController registerAdClass method e.g. something like:

What could make it even more interesting is to start off with an even ratio between multiple adapters and after a minimum amount of clicks has been reached, prioritize the adapter that produces most clicks by the user. iAd has a delegate method called bannerViewActionShouldBegin and RevMob has one called revmobUserClickedInTheAd that could be used to track this, not sure about AdMob. Something like if((iAdClicks + revMobClicks) > 10 && iAdClicks/(iAdClicks + revMobClicks) >= 0.5) { register iAd adapter first }else{ register RevMob adapter first}.

Thoughts?

PS I personally intend to control the ad network ratios remotely via GroundControl based on highest eCPM.

larsacus commented 11 years ago

This is an excellent idea. If this were to be done, I would prefer that it be generalized in such a way that you could easily use ground control or any other way to remotely control the ad priority or filling modes between ad networks. That way if a given ad network were performing better than another, you simply adjust its settings.

It would have to have an interface method like you mentioned above, but also be able to be overridden at runtime so that you could optionally have the ad controller pull the settings from an arbitrary location that the developer specifies (like a block of code or a custom method to invoke) in order to use a service like ground control.

Off the top of my head (with your thoughts above), this is what I see as possible implementations for this:

  1. Compile-time setting of ratio with a static method: - (void)registerAdClass:(Class)class withPublisherId:(NSString *)publisherID withRatio:(CGFloat)adRatio
  2. Compile-time blocks on an adapter that pull settings at runtime:
@property (nonatomic, copy) CGFloat(^ratioBlock)(CGFloat tapRatio);
@property (nonatomic, copy) NSUInteger(^priorityBlock)(void);
  1. Combine the two methods above and have the user specify a specific adapter instance with the above properties already configured (publisherID, update blocks, etc). This would require some refactoring in the adapters to support persisting instances. The only problem this presents is that some ad networks do not have a concept of "pausing" ad requests, which is why I'm currently just deallocating the ad instances and recreating them when I need them.
    - (void)registerAdapter:(id<TOLAdAdapter>)adapterInstance;

I'd like for this to be scalable for other settings within an adapter without also cluttering up the public interface. I would like to avoid the "swiss-army knife" approach to this class.

Let me know what you think.

Fred10932 commented 11 years ago

That looks like a great approach -- I like the idea of both a "set it and forget it" option (which of course still allows adjustments of ad network ratios at the time of app updates) as well as a more active (remote) management of the ad network ratios. No extra lines of code in the app delegate also makes sense, although adding a line into - (void)applicationWillEnterForeground:(UIApplication *)application may be necessary to destroy banners and reregister adapters as needed (unless you can think of a better way?). How would you like to move forward, considering I produce lower quality code? Do I get started in a fork anyway or do you prefer to take the lead right away on this?

larsacus commented 11 years ago

I think that if you're interested, you should begin work on it. I'm going to start a new branch to begin this work. I don't have a timetable on completion of this, however, since this is a side project of mine.

Fred10932 commented 11 years ago

See a first try @ https://github.com/Fred10932/LARSAdController/tree/Managed_Adapter

Had to modify Groundcontrol somewhat to deal with servers that return a Plist as text/plain instead of application/x-plist.

I also added a change of adapters after a specified time. The reasoning behind this is that if user hasn't clicked on the ad after a few minutes, the likelihood is small that user will ever click on it. To do: