In this tutorial we show how to integrate the ArenaDaemon's ADV feature into an iOS application.

More in depth, we are going to show how to display advertising banners and videos.

 

 Our thanks goes to Matteo Morelli for the development of the Swift version of the sample project.

 

We assume that the developer already owns an account into the ArenaDaemon web platform and

owns the knowledge for creating a new application and retrieving the correspondent appKey.

For more information about how to create a developer account and for setup a new application,

please refer to the chapter "Create an appKey".

 

 

WARNING : if you are planning to implement GhostOver ads, be aware that,

for devices equipped with low performances hardware (iPad 1st generation, iPad Mini,

iPhone <= 4s) you could face unpredictable behaviours and crashes due to OpenGL ES

as primary iOS rendering engine.

 

In order to make everything work as expected, you need go to Product/Scheme/Edit Scheme,

select the Options tab and set Metal or Disabled for 'GPU Frame Capture' option as shown below 

 

go_warning.png 

 

Our thanks go to Alessia Pizzitola from OutOfTheBit for discovering this flaw 

and helping us to fix it!

 

 

Create a new Xcode project and include the SDK as shown in chapter SDK Installation and setup.

 

The next step is to create an UIViewController (we'll give it the name 'MainViewController') in which

we'll load a banner and a clip.

 

Before doing any action with the daemons, the local player needs to be authenticated so we need

to add the following code to the AppDelegate class :

 

 

- (BOOL)application:(UIApplication *)application

        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

 

        .....

        // init BDArenaConnector and register current object to observers

        [BDArenaConnector initializeWithAppKey:@"YOUR_APP_KEY" 

                runInSandboxEnvironment:YES];

        [[BDArenaConnector getInstance] registerEventsObserver:self];

        [[BDArenaConnector getInstance] requestAuth];

        .....

 

        return YES;

}

 

- (void) dealloc{

        // unregister current object from observers

        [[BDArenaConnector getInstance] unregisterEventsObserver:self];

}

 

#pragma mark - BDArenaConnectorDelegate

 

- (void) arenaConnector:(BDArenaConnector*)connector

        authReceivedForLocalPlayerWithData:(BDArenaPlayerData*)playerData

        alreadyMet:(BOOL)alreadyMet

        isOffline:(BOOL)isOffline{

        

        // set root controller

        MainViewController* main= [[MainViewController alloc

                initWithNibName:@"MainViewController" bundle:nil];

 

        self.window.rootViewController = main;

}

 

- (void) arenaConnector:(BDArenaConnector*)connector

        authFailedForLocalPlayerWithError:(NSError*)error{

        // handle errors

}

 

 

Within the MainViewController, we need to create two UIButton :

  • The first one (startStopBannerRotationButton) will manage the auto refresh status related to the 320x53 banner display.
  • The second one (getAdClipButton) will create an UIView in which the SDK will load and show an ad clip.

In the viewDidAppear method of the MainViewController class, we'll create an UIView in which we'll place, as subview, the banner's view. Here, we'll also tell the SDK to enable the rotation for the 320x53 banner format :

 

 

- (void) viewDidAppear:(BOOL)animated{

        [super viewDidAppear:animated];

 

        // create the container view for the banner

        bannerContainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 53)];

        bannerContainerView.backgroundColor = [UIColor grayColor];

 

        // add the banner to the container view and add it to the viewController's main view

        [bannerContainerView addSubview:[[BDArenaConnector getInstance]

                advGetBannerViewForAdFormat:BDArenaAdvBannerFormat320x53]];

 

        // add the container view to the viewController's main view

        [self.view addSubview:bannerContainerView];

 

        // position the banner view

        bannerContainerView.center = CGPointMake(self.view.bounds.size.width/2, 50);

 

        // tell the SDK to enable rotation for 320x53 banner format

        [[BDArenaConnector getInstance]

                advEnableRotationForBannerFormat:BDArenaAdvBannerFormat320x53];

}

 

 

Now we need to add the code for the actions triggered by the two UIButton.

 

For the action startStopBannerRotationButtonPressed we'll set : 

 

- (IBAction)startStopBannerRotationButtonPressed:(id)sender{

 

        if([[BDArenaConnector getInstance] advIsBannerRotationActive]){

                // stop rotation

                [[BDArenaConnector getInstance] advBannerStopRotation];

 

                // change button's title

                [startStopBannerRotationButton 

                        setTitle:@"start banner rotation" forState:UIControlStateNormal];

        }

        else{

                // start rotation

                [[BDArenaConnector getInstance] advBannerStartRotation];

 

                // change button's title

                [startStopBannerRotationButton 

                        setTitle:@"stop banner rotation" forState:UIControlStateNormal];

}

 

 

For the action getAdClipButtonPressed we'll set :

 

- (IBAction)getAdClipButtonPressed:(id)sender{

 

        // create a view container for the clip

        UIView* clipView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];

        clipView.backgroundColor = [UIColor blackColor];

        clipView.autoresizingMask =

                UIViewAutoresizingFlexibleWidth |

                UIViewAutoresizingFlexibleTopMargin |

                UIViewAutoresizingFlexibleBottomMargin;

        [self.view addSubview:clipView];

 

        // position it somewhere

        clipView.center = CGPointMake(self.view.center.x, self.view.center.y);

 

        // if you like to customize adClip components appearance, allocate an      

        // BDArenaAdClipConfigData object and configure its properties.

        BDArenaAdClipConfigData* config = [[BDArenaAdClipConfigData alloc] init];

 

        // for the 'countdownText' property, you can use [time], [duration] and [percent] macros...

        config.countdownText = @"My app will start in [time] seconds ([percent]% played)...";

        config.labelPosition = BDArenaAdvAdClipCountdownLabelPositionBottom;

        config.textAlignment = NSTextAlignmentLeft;

        config.clickThruAlertTitle = @"Thanks for the click!";

        config.clickThruAlertMessage = @"Do you want to open the website?";

        config.clickThruAlertCancelButtonTitle = @"No, thanks";

        config.clickThruAlertOpenButtonTitle = @"Yeah!";

 

        // disable 'getClipButton'

        getAdClipButton.enabled = NO;

 

        // make the call ;)

        [[BDArenaConnector getInstance] advRequestAdClipInView:clipView

                                                                withConfiguration:config];

}

 

 

Tapping the 'get ad clip' button, the app tells the SDK to retrieve a clip.

When an ad clip is successfully retrieved, the SDK notifies the event by calling

the arenaConnector:clipReadyToPlayInView: method of the BDArenaConnectorDelegate protocol.

 

If this event occurs, the developer can start the clip playback by calling advPlayAdClipInView:

 

 

- (void) arenaConnector:(BDArenaConnector*)connector 

        clipReadyToPlayInView:(UIView*)clipContainerView{

                

                // an adClip has been found... just play it!

                [[BDArenaConnector getInstance] advPlayAdClipInView:clipContainerView];

}

 

 

In order to be notified when the clip ends, the developer needs to override the

arenaConnector:clipInView:didFinishPlaybackWithReason: method of BDArenaConnectorDelegate protocol.

The reason parameter informs about the event that triggered the end of the clip playback

(the playback reached the end or the player did tap the skip button) :

 

 

- (void) arenaConnector:(BDArenaConnector*)connector

        clipInView:(UIView*)clipContainerView

        didFinishPlaybackWithReason:(BDArenaAdvAdClipDidFinishReason)reason{

 

        // remove the container view from its superview

        [clipContainerView removeFromSuperview];

 

        // enable 'getClipButton'

        getAdClipButton.enabled = YES;

 

        switch (reason) {

                case BDArenaAdvAdClipDidFinishReasonPlaybackEnded:{

                        // the clip did reach end;

                        break;

                }

                case BDArenaAdvAdClipDidFinishReasonPlaybackSkipped:{

                        // the user did skip the clip

                        break;

                }

                default:

                        break;

        }

}

 

 

For the action getGhostOverButtonPressed we'll set :

 

- (IBAction)getGhostOverButtonPressed:(id)sender{

         [[BDArenaConnector getInstance] advRequestGhostOverAd];

}

 

 

Tapping the 'get GhostOver' button, the app tells the SDK to retrieve a GhostOver ad.

When an ad is successfully retrieved, the SDK notifies the event by calling

the arenaConnector:ghostOverReadyToPlayInWindow: method of the BDArenaConnectorDelegate protocol.

 

If this event occurs, the developer can start the clip playback by calling advPlayGhostOverAd

 

 - (void) arenaConnector:(BDArenaConnector*)connector

        ghostOverReadyToPlayInWindow:(UIWindow*)window{

                

                // a GhostOver ad has been found... just play it!

                [[BDArenaConnector getInstance] advPlayGhostOverAd];

}

 

 

In order to be notified when the ad ends, the developer needs to override the

arenaConnector:ghostOverInWindow:didReachCompletionAtPlaybackTime:,

arenaConnector:ghostOverInWindow:didBreakAtPlaybackTime: or

arenaConnector:ghostOverInWindow:pauseOnUnsupportedOrientationTimedoutWithTimeout:

methods of BDArenaConnectorDelegate protocol.

 

 

 

The application will look like :

tutorial_advertising


 

 

Sample project

Download the sample project for this tutorial [Objective-C | Swift].