Taming Apple iAds (We’re only in it for the money) | Peter van Ooijen

:

Getting a MonoTouch app into Apple’s AppStore is no big problem. Getting an app with ads in was a little more cumbersome. Not  because of MonoTouch; the review on ads just requires some extra attention. Some, but not all criteria are explicitly mentioned  in the review guidelines:

  • Apps that contain empty iAd banners will be rejected
  • AdBanners should not be (partly) hidden.
  • Marketing screenshots should not show test ads

In this post I will describe how I got my app accepted.

Ads, available since iOS 4.0, are a way to try get some revenue from a free App. Implementing them is a matter of signing an iAds contract in iTunesConnect (the account you need to submit an app to the store) and placing an ADBannerView component on a View of the app. This component will manage all interaction with Apple’s ads server. It works out of the box, even in the emulator.

AdBuster0

The “Test Advertisement” is served by Apple.

Provide an ADBannerViewDelegate

The nice thing about the ADBannerView is that it writes clear messages to the output of MonoDevelop.  In case there is no connection to the internet the banner will stay blank. According to the requirements a banner is not allowed to be blank. The banner should handle ad-failllure in the banner’s delegate.

When the delegate is not set the banner will report that to the output.

Implementing the basics of this delegate is very straightforward.

using System;

using MonoTouch.iAd;

 

namespace AdBuster

{

    public class MyAdBannerDelegate : ADBannerViewDelegate

    {

        public MyAdBannerDelegate ()

        {

        }

 

        public override void AdLoaded (ADBannerView banner)

        {

            banner.Hidden = false;

        }

 

        public override void FailedToReceiveAd (ADBannerView banner, MonoTouch.Foundation.NSError error)

        {

            banner.Hidden = true;

        }

    }

}

 

The banner is passed to the events. In case a new ad comes in the banner is shown, in case there is no ad the banner is hidden.

The delegate is assigned to the banner when the view is loaded.

public override void ViewDidLoad ()

{

    MyAdBanner.Delegate = new MyAdBannerDelegate();

    base.ViewDidLoad ();

}

Provide alternative content for the ADBannerView

In case there is no add the app will now look like this:

AdBuster2

There is no visible add-banner,  so at first sight you are meeting the requirements. But the review of an app is done by humans. To them the blank space looks the same as an empty add-banner and the app will be rejected. What works is hiding another control, like a label or a button, behind the banner. When the banner is hidden that control shows up and will satisfy the app reviewer.

Only show the ADBannerView when the content fits

The size of the add-banner varies, for instance when the phone is rotated. The banner will demand an add from the add-server which fits. When the size of the banner changes this size has to be set. This is no big deal, the ADBannerView class has  clear members to do that.

This is the full code:

public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)

{

    return true;

}

 

public override void WillRotate(UIInterfaceOrientation toInterfaceOrientation, double duration)

{

    MyAdBanner.Hidden = true;

    base.WillRotate (toInterfaceOrientation, duration);

}

 

public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation)

{

    var isPortrait = UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.Portrait || UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.PortraitUpsideDown;

    MyAdBanner.CurrentContentSizeIdentifier = isPortrait ? ADBannerView.SizeIdentifierPortrait : ADBannerView.SizeIdentifierLandscape;

    MyAdBanner.Hidden = false;

    base.DidRotate (fromInterfaceOrientation);

}

The first method is needed to enable rotation. The second is fired before rotation and hides the banner. The third one sets the size and shows the banner. At first sight it might seem an overkill to hide the banner during the short moment of rotation itself. But not hiding that will cause the banner to write a clear rejection message to the output

AdBuster1

 

Check your screenshots

The review of your app extends the app itself. In the last round the screenshots of my app were rejected because they did show the Apple Test Add. Which was concerned “placeholder text” . Something of a chicken-egg problem; as long as the app is not accepted it will present Apple’s placeholder add; as long as it shows the placeholder the app would not be accepted. I just censored the images and got accepted the next day.

Now, let’s see if I can make some money on this Smile