Welcome to Day 29 of the 31 Days of iOSYesterday, we discuss a few different ways you can indicate to users that there is some background or network activity occurring with your application.  Today, we’re going to talk about how to monitize your app with advertisements using iAd.  There are alternatives to iAd (such as adwhirl) but we’re going to focus on Apple’s own advertising implementation.  When you use iAd, you’ll get 70% (as of posting) of the revenue generated from user clicks.  We’ll be starting with a brand new project, but if you’d like to follow along with the completed code, you can access it here.

Creating our project and handling the UI

Open up Xcode and choose File, New, Project.  We’ll use a Single View Application and name it DayTwentyNine:

Day 29 New project

Now open the MainStoryboard.storyboard and drag a Ad BannerView from the UI element selector in the bottom right of Xcode onto the bottom of the view.  When you’re done, it will look like this:

Ad BannerView in Storyboard

While you are in the storyboard, open the Assistant Editor from the top right of Xcode and control + click and drag from the ADBannerView to your code behind to create a new outlet.  Your code should now look like this:

Now try running your app in the simulator.  It’s going to crash right away and if you look in the debug console, you’ll see this error:

'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named ADBannerView'

We’ll solve this problem by adding the iAd framework.

Adding the iAd Framework

Click on your project in the Project Navigator to bring up your project and target properties.  Click on the Build Phases tab and expand the Link Binary with Libraries section and then click the +:

Linking binaries

From that, select iAd.framework and click Add:

iAd.framework

Now if you run your app, you’ll crash again, but with a different error.

[AppDeveloper]: ADBannerView: Unhandled error (no delegate or delegate does not implement didFailToReceiveAdWithError:): Error Domain=ADErrorDomain Code=4 "The operation couldn’t be completed. Application has iAd Network configuration error"

and:

[AppDeveloper]: ADBannerView: Unhandled error (no delegate or delegate does not implement didFailToReceiveAdWithError:): Error Domain=ADErrorDomain Code=5 "The operation couldn’t be completed. Banner view is visible but does not have content"

The reason we’re seeing the errors is that to use an Ad BannerView you must implement the ADBannerViewDelegate.

Implementing the delegate

Open the ViewController.h and add an import statement for iAd/iAd.h.  Next make the class implement the ADBannerViewDelegate.  Now your header file should match this:

Now switch over to the ViewController.m file.  First we need to set the banner’s delegate to be our View Controller:

With that done, we can add the methods needed to actually implement the ADBannerViewDelegate protocol:

Now you can run your app successfully.

Checking out the test ad

When you run your app in the iPhone simulator, you’ll see a test ad appear at the bottom of the app:

App with Test Ad showing up

If you tap on the ad, you’ll be taken to a full page version of the ad:

Full Screen iAd

After that loads, you’ll see a multi-page ad for putting iAds into your app.  Tap the X to return to the app so you can see the ad at the bottom again.  Now if you rotate your simulator, you’ll see that the ad doesn’t quite look right:

Lanscape ad screwed up

The ad is showing up properly sized, but there is some white space beneath it.  Let’s fix this now.

Handling rotation

We’re going to need to do a little bit of code to handle the rotation of our ad.  Open back up ViewController.m.  We’re going to implement the viewDidLayoutSubviews method:

Here we’re checking to make sure the banner has been loaded by checking it’s bannerLoaded property.  If it is loaded, we can then set the y coordinate of the banner’s frame to the size of the contentFrame (which we get from the view.bounds) and subtract the height of our banner.  So when the iPhone simulator goes into landscape, it’s dimensions will  be 480x300.  So the y coordinate of the banner’s frame ends up being set to 268 (300 height of the frame – 32 height of the banner).  Now when we run, we get a proper looking landscape banner:

Landscape ad looking good

Why aren’t my ads showing up?

If you’ve already ran your app a few times, you may notice that you’re not seeing an ad every once in a while.  This is because when you’re in development mode and are testing (i.e. your app wasn’t installed from the store), Apple’s ad servers will sometimes deliver errors to your app. This is so that you can test correctly handling ads not being appropriately delivered to your app.  You can test this out by putting a NSLog call in the bannerView: didFailToReceiveAdWithError.  The idea being that if this occurs, you wouldn’t show the ad and would resize any other views, if necessary. 

Other Important Methods

In order to quickly implement the ADBannerViewDelegate we added a few methods earlier but didn’t explain them.  Let’s talk about them now.  First we have bannerViewActionShouldBegin: willLeaveApplication which is called when the user taps an ad.  This method can be used to override whether the action triggered by the ad should be performed.  Where we’re returning YES no matter what right now, if you instead return NO, you’d never be taken to the full screen ad when tapping on the ad.  Remember, though, that users will expect whatever action the ad does to occur when they tap it.  Be careful when deciding not to proceed with the ad action.  This method also receives a boolean parameter that indicates if the ad action is going to leave your application.  If the ad is not going to leave the application (which it won’t right now) you should consider that an indicator that your user interface is going to be obscured.  When that happens you should disable any sounds or animations.  You should also pause any activities that require user input (such as in a video game).

If the ad does cover your user interface, when the user returns to your app then another method (we haven’t yet seen) is called.  That method is bannerViewActionDidFinish.  This method is also called if the user does something inside the advertisement that causes them to leave your application.  So you should return quickly from this method (remember, your app could be getting backgrounded).  You should also not think of this as a method to “unpause” your application.

The bannerViewDidLoadAd method is called when an ad is ready to be displayed.  In our app, if you put a log statement or a breakpoint in this method, you will have to pay attention to see it, but the ad will actually show up in the simulator before this method is called.  However, this method will be called on your banner ad even if it isn’t part of the current view hierarchy.  You can use this to hide the ad until it’s been loaded and then display or animate it in. 

Full-Screen Ads for iPads

Full-screen advertisements were made available in iOS 4.3 and are specific to the iPad platform.  We wont talk about these ad types today but you can read more about full-screen ads in the Apple documentation.

Enabling ads for app launch

When you’re ready to launch your app to the App Store, you need to log into iTunes Connect.  After logging in, click on the Manage Your Applications link on the right side, then select the app you are launching.  There is then a button to Set Up iAd NetworkThis documentation will walk you through the rest of the process of signing up for iAds.  Essentially you need to agree to a contract (unless you’ve already done so) and then select an age rating for the ads that will be delivered to your app (essentially, will children use your app or not).  After that, you’re done and you’re app, when installed from the App Store, will feature ads.

Best practices from Apple

Apple includes a few best practices in your application which I’ll explain here.

First, don’t create a banner view unless you plan on displaying it.  Once you’ve created your banner view, ads start being cycled through it.  If those ads aren’t actually being displayed, the ones available will be depleted.

Along the lines of the last tip, if your user navigates away from the screen with the banner view on it, set the delegate to nil and stop displaying ads so you’re not continuing to cycle through ads.

It can take a while to go from creating a banner view to having an ad ready to display.  For that reason, you shouldn’t try to show a banner on a screen that is only visible for a short period of time (like a splash screen on launch).  However, if you do want to do this on short lived screens, you should create a single banner view and use the same one throughout your application.  You can read more about how to do this sort of thing with singletons here.

If your app features a rich media experience (such as video), iAd will consume additional memory to display the ad to the user.  This means other areas of your application may need to be released to increase the amount of memory available.  Plan accordingly.

Conclusion

Today we took a look at how to use advertisements in your app with iAd.  Remember that iAd isn’t the only option (unless Apple decides to not certify apps using other ad providers).  Ads are a great way to monetize your application.  Many developers will release a free version of their app which features ads and then a paid version that doesn’t use ads.  Fortunately, its very simple to put iAd into your applications. You can download the completed source code from this sample here.


Chris Risner