Showing posts with label iAds. Show all posts
Showing posts with label iAds. Show all posts

Saturday, April 20, 2013

Tutorial 29 - Codea v1.5.2: Objective C Add On, iAds


Figure 0. Codea implementing iAds - showAdFromTop()

29.1 Overview


CodeaAddon is an experimental protocol for adding native extensions to exported Codea projects. You must deal with Lua directly to register your functions and globals. This protocol should be considered alpha and is subject to change in future Codea releases.

With that disclaimer out of the way, let's have a look at what we can do with this new functionality. We have previously done tutorials to add Game Center and iAd functionality using the old runtime but with the great new export to Xcode functionality, this is no longer the best way to skin that particular cat.

You may want to re-read our previous tutorial on implementing iAds in Codea as we won't cover the same background in this tutorial.

We will build on the previous tutorial which uses the audio add on. This has the added benefit of showing how you can stack a number of add ons to the same project.

Note that before you start adding advertising support to your applications available on iTunes, you must first agree to the iAd Network agreement. Further, you must explicitly enable iAd for each application in iTunes Connect. As a part of the iAd Network, you control the kinds of ads that are delivered to your application. We don't need to do this to test it in the simulator though.


Figure 1. Add the iAd Framework to your App



29.2 Add the iAd Framework to your App


Fire up Xcode and load the exported version of your Codea application (See Tutorial 27). Click on the imported project file at the top of the project navigator then in the Build Phases tab, scroll down to the link binary with libraries area and select the drop down arrow. Click on the "+" button below your existing frameworks to add a new framework. Find iAds and click on "Add" (Figure 1).


29.3 Update the AppDelegate Files


In the AppDelegate we need to register our new add on classes. The new AppDelegate.h file now looks like:


//
//  AppDelegate.h
//  AudioDemo
//
//  Used to demonstrate the audio add on and iAds add on libraries
//
//  Created by Reefwing Software on Sunday, 14 April 2013
//  Copyright (c) Reefwing Software. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AudioAddOn.h"
#import "IAdsAddOn.h"

@class CodeaViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) IAdsAddOn *iAdsAddOn;
@property (strong, nonatomic) AudioAddOn *audioAddOn;
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) CodeaViewController *viewController;

@end


And similarly to what we had in the previous tutorial AppDelegate.mm now looks like:


//
//  AppDelegate.mm
//  AudioDemo
//
//  Created by Reefwing Software on Sunday, 14 April 2013
//  Copyright (c) Reefwing Software. All rights reserved.
//

#import "AppDelegate.h"
#import "CodeaViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[CodeaViewController alloc] init];
    
    //  Create and add our AudioAddOn to Codea
    
    self.audioAddOn = [[AudioAddOn alloc] init];
    [self.viewController registerAddon: self.audioAddOn];
    
    //  Create and add our iAdsAddOn to Codea
    
    self.iAdsAddOn = [[IAdsAddOn alloc] init];
    [self.viewController registerAddon: self.iAdsAddOn];
    
    NSString* projectPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"AudioDemo.codea"];
    
    [self.viewController loadProjectAtPath:projectPath];
    
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
}

- (void)applicationWillTerminate:(UIApplication *)application
{
}

@end



29.4 The iAds Add On


Our iAds add on implements two internal booleans, isBannerVisible and showBannerFromTop. Hopefully the use of these should be fairly obvious. We also register three new functions for use within Codea:


  1. showAdFromTop();
  2. showAdFromBottom(); and
  3. hideAd()
Our example project demonstrates the use of all 3 of these functions. We start by displaying Ads from the top of the page (once the ad has been loaded from the ad server). We hide ads when the play button is tapped and then show them from the bottom when the stop button is tapped.

In the simulator apple will send you ad errors regularly (e.g. Ad inventory unavailable) to make sure that your code can handle this. Your app will get rejected if it displays an empty ad banner so the add on takes care of this situation. When displaying the ad banner, it will slide down from the top or up from the bottom depending on which function that you have used. Similarly hideAd() will animate the ad sliding above or below the screen depending on the state of the boolean showBannerFromTop.

Figure 2. Codea implementing iAds - showAdFromBottom()


This example add on only handles ads for an iPad in portrait orientation. We have included device detection macros in IAdsAddOn.h, just remove the comment slashes if you want to use these to position your Ads. To handle different orientations and devices update the banner view frame variables in the two methods:
  1. - (void)showBannerViewAnimated:(BOOL)animated; and
  2. - (void)hideBannerViewAnimated:(BOOL)animated.

If you don't want the banner views to slide to the new position then set animated = NO for the above two methods.

29.5 Download the Code


The complete code listing is available below.




Friday, November 30, 2012

Interlude 14 - Update on MineSweeper Sales


14.1 Overview


MineSweeper was initially launched at the end of August 2012. To date it has been downloaded by 2,484 people which is an average of 20 per day. As the graph above shows, averages don't paint an accurate picture of the download distribution. The first month (September) accounts for 2,393 or 96% of these downloads. Since the end of September, the average download rate has been 1 per day.


14.2 Version 1.7 Release


The first published update to MineSweeper was version 1.7 which made the App universal, included Game Center support and added iAds. You can see the bump in downloads on the release day in the graph above. This bump is a pale shadow compared to the initial release bump (11 vs 471).

14.3 Geographic Distribution


37% of downloads has been from the US which is not unexpected, but the next largest region is Germany at 9% which is curious.



14.4 What can we deduce?


These are only statistics from one application over a 3 month period and the enhancements from v1.7 have only be around for 3 days so we need to be careful not to identify trends that don't exist.
  1. iAds - Requests and Impressions can given you a feel for usage of your App each day. It is very early days so hard to conclude anything yet. In order to maximise revenue the download curve would suggest that you would be better off including iAds in your initial release rather than a subsequent upgrade.
  2. Game Center - will also give you an indication of app usage. In the 3 days that Game Center has been available, 9 people have recorded high scores in the Easy Difficulty leader board.
  3. Geographic Distribution - Based on the geographic download distribution, if we were to localise the app then German would be the first language that we should implement.
  4. Upgrades - For the 3 days that v1.7 has been released there has been 419 upgrades downloaded. We would expect another 100 or so over time but upgrades give you a feeling for how many people keep your App on their device after the initial download.

Saturday, November 17, 2012

Tutorial 23 - Implementing iAds with Codea


23.1 Introduction


A common business model in the App store is to give away your app for free and generate revenue by serving ads to your application. This model has benefits but can annoy your users if done in excess. Everyone likes stuff that is free, so setting a zero cost removes most of the barriers to downloading your app and should maximise download numbers.

Since iOS 4.0 the iAds framework has been available for developers. Using this you can add banner or full screen advertisements to your application. If you are planning to include ads on a screen then you need to ensure that you have left space within your interface to display them. Full screen ads (referred to as interstitial ads by Apple) are only available on the iPad and are only suitable in certain situations, so we wont cover those in this tutorial.

You receive revenue when users view (called impressions) or click advertisements on your app. Some apps use a bit of social engineering to maximise their click through rate. For example the Foxtel (cable TV) app in Australia has ads which appear at the top of the channel selection screen. As per the Apple guidelines these ads are only displayed once the banner has been loaded from the ad server. When this occurs, the ad slides in from the top and moves the content down by the height of the banner. However what happens 50% of the time (for us at least) is that you accidentally tap the ad when you are trying to select a channel.

It is difficult to estimate exactly what revenue you might receive from including iAds in your app. A graph of the impressions that we got for the last year is shown below. There was about 98k in total with 90% coming from one app (Personality). According to Apple the effective revenue per thousand ads (eCPM) served over this period was $0.82. In practice, we get on average $0.25 per day. So while this may not be a get rich quick scheme, it is not bad passive income, particularly given the app I'm deriving revenue on is not optimised for ads. 

We suspect you could do much better with a free game app with high reusability (people tend to use Personality only 2-3 times at best). Apple says that "hundreds of developers are making more than $15,000 per quarter". Given that there are 275,000 iOS developers in the US alone, this is perhaps not that impressive - albeit not all of those developers have iAd enabled apps.




23.2 Banner Views


From a Codea perspective, implementing iAds is easy. If you are happy to display ads on every screen then you just need to leave the appropriate amount of space on your screen to display the ad. In most cases there will be screens that you don't want to display ads on (e.g. the main game screen), so we have extended Codea Lua with a function, showBannerAd(true) to turn ads on and off. For our example, we will only display ads on the Menu and High Score screens.

For the iPad, banner sizes are set at:
  • Portrait: 66 (height) x 768 (width) points - see Interlude 13 if you dont understand the difference between pixels and points.
  • Landscape: 66 (height) x 1024 (width) points.
For completeness, the iPhone banner sizes are 320 x 50 points for a portrait advertisement and 480 x 32 points for a landscape advertisement.

The banner ads are intended to typically appear either at the top or bottom of the display and are provided in two formats so that ads may be displayed when the device is either in portrait or landscape orientation.


23.3 Setup iAds in iTunes Connect


As with Achievements and in-App purchasing, there are some things that you need to enable in iTunes Connect before your app will be able to receive ads from Apple's servers. Log in to your developer account, select iTunes Connect and then click on Manage your Apps. Click on the appropriate App icon and then click on the Setup iAds link (right hand side towards the top).

Answer the question regarding whether the primary target audience for your app is users under 17 years of age and then click Enable iAds and Save.

That's it! You can disable iAds just as simply but changes to your iAd settings will not take effect until your next app version is approved.


23.4 Creating Your Banner Views in the Codea runtime


You should only create a banner view when you intend to display it to the user. Otherwise, it may cycle through ads and deplete the list of available advertising for your application. As a corollary to this, avoid keeping a banner view around when it is invisible to the user. To demonstrate the implementation of iAds in the runtime we will use our old faithful MineSweeper application.

Based on our careful UI planning (or perhaps just through good luck) we happen to have enough space at the top of the MineSweeper Menu screen to fit in a banner ad, so that is where we will put it. As MineSweeper is now a universal application we will need to handle the iPhone sized banners as well. We have more room at the bottom of the iPhone Menu screen when it is in the portrait orientation, so when we detect that device and orientation we will place the banner at the bottom of the view. There is no room for a banner on an iPhone in landscape orientation, so we will disable ads when we detect this combination.

Banner views use a delegate to communicate with your application. Your application will thus need to implement a banner view delegate to handle common events. In particular we need to handle:
  1. when the user taps the banner.
  2. when the banner view loads an advertisement.
  3. when the banner view encounters an error.
Usually you would place this code in the relevant view controller but for simplicity we will handle this in the CodifyAppDelegate (the alternative is to extend the BasicRendererViewController class in the runtime).

If your application supports orientation changes, your view controller must also change the banner view’s size when the orientation of the device changes.

Step 1 - Add the iAd Framework to your App.

Fire up Xcode and load the runtime version of your Codea application. Click on the CodeaTemplate file at the top of the project navigator then in the summary tab, scroll down to the linked libraries area. Click on the "+" button below your existing frameworks to add a new framework. Find iAds and click on "Add".

Step 2 - Update the CodifyAppDelegate Files.

In CodifyAppDelegate.h you need to import the framework you just added using:

#import <iAd/iAd.h>

then modify the class interface definition so that it looks like this:

@interface CodifyAppDelegate : UIResponder<UIApplicationDelegate, ADBannerViewDelegate>

This indicates that the ADBannerViewDelegate protocol will be implemented. We will provide a link to download the updated CodifyAppDelegate files below. We have added two other things to the CodifyAppDelegate files:
  1. A boolean instance variable called displayingAds which is controlled from your Lua code via the modified aGameCenter_Codea class; and
  2. A call back method called iAdDisplayStatusChanged which is used to update the banner view if the MineSweeper game state or orientation changes. This also comes via the modified aGameCenter_Codea class.
Step 3 - Update the other Codea runtime Files.

As we saw in Tutorial 19 when integrating Game Center, there are changes required in LuaState.m, OSCommands.h and OSCommands.m, to allow Lua to communicate with our Objective C code. This mostly comprises registering our new showBannerAd(true or false) function.

In LuaState.m add the following to the  - (void) create method:

    //iAds Function
    LuaRegFunc(showBannerAd);

In OSCommands.h add the following below the similar Game Center definitions:

    //iAds
    int showBannerAd(struct lua_State *L);

Finally, in OSCommands.m add the following method below the Game Center definitions:

int showBannerAd(struct lua_State *L){
    [CodeaGameCenter showBannerAd:lua_toboolean(L,1)];
    return 0;
}

23.5 Codea Lua Code Changes


As mentioned in section 23.2, if you are happy to display adds on every screen then there is no changes required to your Lua code (assuming you left space for the ads). If like us you want to select when ads are displayed, then you need to use the new showBannerAd() function. If you pass true in this function then ads will be displayed and if you pass false, they wont.

As an example, the following shows our updated orientationChanged() function. 

function orientationChanged(newOrientation)

    print("Orientation Change Detected.")
    
    if setupHasRun and gameState == stateRun or gameState == stateWon or 
        gameState == stateLost then
            updateGridLocation()
    end 
    
    if setupHasRun and (gameState == stateMenu or gameState == stateScore) then
        showBannerAd(true)
    else
        showBannerAd(false)
    end
    
end

We also use showBannerAd()  when the gameState changes due to button taps.

The other class we need to modify is the SpashScreen. In the fadeAnimation call back, we turn on ads once the splash screen has faded away.

function fadeAnimationDone()
    
    -- Call back function for Fader complete
    
    gameState = stateMenu
    showBannerAd(true)
    
end

23.6 Download the Updated Runtime & Codea Files


The aGameCenter_Codea and CodifyAppDelegate files are available on GitHub. In addition, the following links allow downloading individual files from DropBox:

Tuesday, September 11, 2012

Interlude 12 - MineSweeper "Sales"

It has been ten days since MineSweeper was released into the wilds of the App Store so I thought I would provide an update on how downloads are going. In summary, downloads are better than I expected, given it is a clone and there are a bunch of established clones already in the store. Figure 1 shows downloads per day (you will probably have to click on the image to see a version big enough to read). 
  
Figure 1. MineSweeper Downloads By Day.
   
It shows the usual trend with a large hump on the day after release followed by a rapid fall over the next four days. You then enter a gentle oscillating phase which will gradually decline if you do nothing else. The small bump on the far right is the weekend kick which I see on most of my App sales. There is many a developer who saw their second day sales, multiplied this by their App price and then by 365 and thought they were on the road to retirement. Alas, my experience is that the post ten day average is a better indicator of long term sales.
   
Figure 2. MineSweeper Download Detail.
    
My guess is that sales will settle down around 50-100 per day, which if I was making any money from them would be fantastic. It does suggest that it would be worth adding iAds to try and extract some return from the effort of writing the App (apart from the educational benefit of course).
  
Figure 3. Early Ranking Data.
  
Looking at how the App ranks is very interesting and illustrates the mysterious Apple ranking algorithm at work. You can see that rank roughly follows downloads (with a slight lag). However, if we look over the ten day period we see a curious result.
  
Figure 4. Ranking Data at the end of the 10 day period.
      
Figure 4 shows that even though sales are not as high as day 2, the rank has continued to climb suggesting that there is some sort of cumulative effect. There is definitely a feedback mechanism whereby the higher you rank, the higher your downloads, which means the higher you rank, etc. The other observation is that it is easy to make progress when you are ranking between 200-300. Getting sub 100 is tougher and top 10 is virtually impossible (unless you call your App Angry Birds).
    
Figure 5. Downloads by Country.
   
Downloads by country contain a couple of surprises. I always expect to do best in America given it is the biggest English speaking market and the UK at number 3 and Australia at number 5 are equally predictable. Germany at number 2 is unexpected and Russia at number 4 is also a pleasant surprise. So thank you to all the German and Russian downloaders. France and China are normally up there and I don't tend to have a lot of luck with the Canadians. Where this sort of information is useful is in deciding what countries to localise your App for. There isn't a lot of text in MineSweeper so localisation would be a fairly simple matter. I have read that localisation can have a dramatic effect on downloads in that market but I havent tried it myself.
    
Figure 6. Reefwing Software Downloads by Product.
     
Figure 6 graphs downloads by product for all of my Apps over a one month period. You can see that the free Apps (MIneSweeper, Personality, LifeAudit, and Number Converter) dominate downloads, however the majority of my revenue comes from LifeGoals. Note that MineSweeper has only been available for 10 days of the month reported on in Figure 6. I will give another update after MineSweeper has been out for a month.
   
Figure 7. Early MineSweeper Reviews.
    
A factor in driving sales is review comments and the number of stars people rate your App at. Trying to bootstrap these by getting your Mum to write a review is always a strategy but in reality unless you have a LOT of friends in MANY countries, real reviews and ratings will swamp any attempt to game the system. BTW - thanks to all the folks from the Codea forum for their positive reviews!
  
Figure 8. Reefwing Software iAds Revenue.
     
The next step in this grand experiment will be to attempt to convert the MineSweeper downloads into cash. Theoretically, iAds should be a fairly good mechanism for this. However, looking at Figure 8 you will see that my current revenue from iAds in the Personality App can only be called pathetic. 
       
Let's see what MineSweeper can do...