//
you're reading...

Programming

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!



Do you enjoy this post? Enter your e-mail address below to receive articles like this one in your mailbox.

Free Updates!

Learn how to grow your indie business while keeping your day job.

Categories

Archives

Keep updated!

Don't miss out on new articles!