Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton class for displaying iAds for iPhone

I have written a Singleton Class for managing iAds.The iAds pop up after 5 seconds of the user inactivity. The idleTimerExceeded call generate a notification to show the iAd. This code works fine for my requirements but since I am new to iOS development, my application sometimes hangs unexpectedly after integrating this code. This code results in lots of warnings etc. I would like to optimize my code in terms of memory and performance.

I would be very thankful for your kind suggestions and reviews.

Below is my code:

iAdSingleton.h

#import <Foundation/Foundation.h>
#import "AppDelegate.h"
#import "iAd/iAd.h"

@interface iAdSingleton : UIViewController<ADBannerViewDelegate> {
    ADBannerView *adView;
    UIViewController *displayVC;
    NSTimer *idleTimer;
    BOOL isItFirstTime;
}
@property (nonatomic, retain) ADBannerView *adView;
@property (nonatomic, retain) UIViewController *displayVC;
@property (nonatomic) BOOL isItFirstTime;

+ (id) shareAdSingleton;
- (void) resetIdleTimer;
- (void) idleTimerExceeded;

@end

iAdSingleton.m

#import "iAdSingleton.h"

@implementation iAdSingleton

static iAdSingleton* _sharedAdSingleton = nil;

BOOL bannerVisible = NO;
BOOL controlAccessBannerVisibility = NO;
@synthesize adView, displayVC;
@synthesize isItFirstTime;

#define kMaxIdleTimeSeconds 5.0

+(id)sharedAdSingleton
{
    @synchronized(self)
    {
        if(!_sharedAdSingleton)
            _sharedAdSingleton = [[self alloc] init];
        return _sharedAdSingleton;
    }
    return nil;
}

+(id)alloc
{
    @synchronized([iAdSingleton class])
    {
        NSAssert(_sharedAdSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
        _sharedAdSingleton = [super alloc];
        return _sharedAdSingleton;
    }

    return nil;
}

-(id)init
{
    self = [super init];
    if (self != nil) {

    /*                  Initialize The Parameters Over Here                  */

        //adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 480, 0, 0)];
        adView = [[ADBannerView alloc] init];
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
        self.adView.delegate=self;
        [self resetIdleTimer];
    }
    return self;
}

-(void)dealloc
{
    displayVC = nil;
    if (adView) {
        [adView removeFromSuperview]; //Remove ad view from superview
        [adView setDelegate:nil];
        adView = nil;
    }
    [super dealloc];
}

-(UIViewController *)viewControllerForPresentingModalView
{
    return displayVC;
}

- (void)bannerViewDidLoadAd:(ADBannerView *)banner 
{
    banner.hidden = NO;
    if(!bannerVisible){
        NSLog(@"Banner Changes 1 - Purpose: Visibility");
        // [UIView beginAnimations:@"bannerAppear" context:NULL];
        // banner.frame = CGRectOffset(banner.frame, 0, -100);
        // [UIView commitAnimations];
        bannerVisible = YES;
        controlAccessBannerVisibility = YES;

    }
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    //NSLog(@"Unable to receive Ad.");
    NSLog(@"Banner Changes 2 - Purpose: Unable to Receive Ad.");
    banner.hidden = YES;
    if(bannerVisible){
        [UIView beginAnimations:@"bannerDisappear" context:NULL];
        banner.frame = CGRectOffset(banner.frame, 0, 100);
        [UIView commitAnimations];
        bannerVisible = NO;
    }
}

- (BOOL) bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
    NSLog(@"Pause anything necessary");
    return YES;
}

- (void) bannerViewActionDidFinish:(ADBannerView *)banner
{
    NSLog(@"We now resume to normal operations");
}

- (void)resetIdleTimer {

    if (!idleTimer) {
        idleTimer = [[NSTimer scheduledTimerWithTimeInterval:kMaxIdleTimeSeconds
                                                      target:self
                                                    selector:@selector(idleTimerExceeded)
                                                    userInfo:nil
                                                     repeats:NO] retain];
    }
    else {
        if (fabs([idleTimer.fireDate timeIntervalSinceNow]) < kMaxIdleTimeSeconds-1.0) {
            [idleTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:kMaxIdleTimeSeconds]];
            /*
             Notification: HideAd
             */

            NSLog(@"Notification Generated For HideAd");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"HideAdBanner" object:nil userInfo:nil];

        }
    }
}

- (void)idleTimerExceeded {

    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    if (appDel.adVisible == NO) {
        NSLog(@"Notification Generated For ShowAd");

        /*
         Notification: ShowAd
         */

        if (controlAccessBannerVisibility == YES) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"ShowAdBanner" object:nil userInfo:nil];
        }
    }
}

@end
like image 850
muneikh Avatar asked Oct 22 '22 19:10

muneikh


1 Answers

This is what you need. This code is thread safe as well as will not have any memory issue and warnings.

+ (iAdSingleton *) sharedInstance
{
    static dispatch_once_t onceToken;
    static iAdSingleton * __sharedInstance = nil;

    dispatch_once(&onceToken, ^{
        __sharedInstance = [[self alloc] init];
    });

    return __sharedInstance;
}
like image 72
Kuldeep Avatar answered Dec 24 '22 11:12

Kuldeep