Integrating iAd with Cocos2D

Yesterday I was toying around with incorporating an iAd banner to my Cocos2D game. It was quite a struggle since the two didn’t play nicely together.

The first issue was that Cocos2D’s CCGLView – which is the director’s primary view – doesn’t support auto layout. Initially I used a scene to manage iAd’s ADBannerView – whenever an advertisement is ready then the scene will add the banner view as a subview of the director’s view and place some constraints to it. However the game crashed just after the constraints were added:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. CCGLView's implementation of -layoutSubviews needs to call super.'

Upon closer inspection, apparently [CCGLView layoutSubview] doesn’t call [UIView layoutSubview] and that what caused the crash. I could modify CCGLView to add this call and perhaps submit a patch to the Cocos2D team – but then it’ll take quite some time to get it incorporated to the main distribution, if the patch got approved at all (and that’s a big “if”).

Facing this then I tried adding the banner view to the director’s parent view. However this failed with a “ADBannerView must be part of a view hierarchy managed by a UIViewController”. Then I was stuck again.

Fortunately after googling around I found a way to send a message to the superclass’ superclass (i.e. the grandparent class) by making use of an Objective-C runtime function. Then it’s quite straightforward to make a subclass of CCGLView that supports autolayout:

//
//  BSGLView.h
//  AirKill
//
//  Created by Sasmito Adibowo on 07-06-14.
//  Basil Salad Software, http://basilsalad.com
//
//  This code is in the public domain.

#import "CCGLView.h"

@interface BSGLView : CCGLView

@end

//
//  BSGLView.m
//  AirKill
//
//  Created by Sasmito Adibowo on 07-06-14.
//  Basil Salad Software, http://basilsalad.com
//
//  This code is in the public domain.
//

#import <objc/message.h>
#import "BSGLView.h"

@implementation BSGLView


-(void)layoutSubviews
{
    // We need this because CCGLView doesn't call UIView layoutSubviews and we need to add subviews
    
    Class granny = [[self superclass] superclass];
    struct objc_super theSuper = {self, granny};
    objc_msgSendSuper(&theSuper,_cmd);
    
    [super layoutSubviews];
}

@end

I then added used this class instead for CCDirector’s view and it now works nicely hosting a banner view on top of the game.

PS: you can use this gist instead to download the code above instead of taking the trouble to copy-paste it from this post.

That’s all for now. until next time!



Avoid App Review rules by distributing outside the Mac App Store!


Get my FREE cheat sheets to help you distribute real macOS applications directly to power users.

* indicates required

When you subscribe you’ll also get programming tips, business advices, and career rants from the trenches about twice a month. I respect your e-mail privacy.

Avoid Delays and Rejections when Submitting Your App to The Store!


Follow my FREE cheat sheets to design, develop, or even amend your app to deserve its virtual shelf space in the App Store.

* indicates required

When you subscribe you’ll also get programming tips, business advices, and career rants from the trenches about twice a month. I respect your e-mail privacy.

0 thoughts on “Integrating iAd with Cocos2D

Leave a Reply