iphonedevcon 2010: cooking with iad

30
cooking With Iad JOnathan Saggau / Noah Gift Tuesday, September 28, 2010

Upload: noah-gift

Post on 18-Jun-2015

1.405 views

Category:

Technology


0 download

DESCRIPTION

Step by Step Tutorial on converting Core Data Books into an iAd based application.

TRANSCRIPT

Page 1: iphonedevcon 2010:  Cooking with iAd

cooking With IadJOnathan Saggau / Noah Gift

Tuesday, September 28, 2010

Page 2: iphonedevcon 2010:  Cooking with iAd

The Talk in a Nutshell

Tuesday, September 28, 2010

Page 3: iphonedevcon 2010:  Cooking with iAd

Agenda

• iAd Overview• Mobclix and iAd manual Integration • Integrating iAds into an app: Apple’s

Core Data Books sample• Demos and other neat stuff

Tuesday, September 28, 2010

Page 4: iphonedevcon 2010:  Cooking with iAd

Ad Delivery Strategy

• Use iAD when it is available• Higher CPM• Better Looking

• Use mobclix otherwise• Internationally• on < iOS 4.0 (read: orig. iPhone)

Tuesday, September 28, 2010

Page 6: iphonedevcon 2010:  Cooking with iAd

Core Data Books From apple

Show defaulthg update --rev 1 Tuesday, September 28, 2010

Page 7: iphonedevcon 2010:  Cooking with iAd

• Adding the iAd Framework

Adding iAd to Core Data Books Adding iAd Framework

hg update --rev 1 Tuesday, September 28, 2010

Page 8: iphonedevcon 2010:  Cooking with iAd

Adding a Banner#import "AddViewController.h"#import <iAd/iAd.h>

@interface RootViewController : UIViewController <NSFetchedResultsControllerDelegate, AddViewControllerDelegate, ADBannerViewDelegate> {! NSFetchedResultsController *fetchedResultsController; NSManagedObjectContext *managedObjectContext;! NSManagedObjectContext *addingManagedObjectContext;! ADBannerView *iadBanner; @private BOOL showingIAdBanner;}

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;@property (nonatomic, retain) NSManagedObjectContext *addingManagedObjectContext;@property (nonatomic, retain) IBOutlet UITableView *tableView;@property (nonatomic, retain) ADBannerView *iadBanner;

- (IBAction)addBook;- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;

@end

Tuesday, September 28, 2010

Page 9: iphonedevcon 2010:  Cooking with iAd

Adding a Banner

• Do it in code if you want to support < iOS 4.0 (original iPhone)

-(ADBannerView *)iadBanner{ if (!iadBanner) { Class bannerClass = NSClassFromString(@"ADBannerView"); if (bannerClass) { iadBanner = [[ADBannerView alloc] initWithFrame:CGRectZero]; [iadBanner setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin]; iadBanner.requiredContentSizeIdentifiers = [NSSet setWithObjects:ADBannerContentSizeIdentifier320x50, ADBannerContentSizeIdentifier480x32, nil]; [self.view addSubview:iadBanner]; CGRect viewFrame = [[self view] frame]; CGFloat width = viewFrame.size.width; [iadBanner setFrame:CGRectMake(0, self.tableView.frame.size.height, width, width == 480. ? 32. : 50.)]; [iadBanner setDelegate:self]; } } return iadBanner;}

Tuesday, September 28, 2010

Page 10: iphonedevcon 2010:  Cooking with iAd

iAD Delegate Protocol#pragma mark iAD Delegate// This method is invoked each time a banner loads a new advertisement. Once a banner has loaded an ad, // it will display that ad until another ad is available. The delegate might implement this method if // it wished to defer placing the banner in a view hierarchy until the banner has content to display.- (void)bannerViewDidLoadAd:(ADBannerView *)banner;{ [self showIAdBanner:YES];}

// This method will be invoked when an error has occurred attempting to get advertisement content. // Possible error codes defined as constants in ADManager.h.- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error;{ // no iAd adds, so try mobclix [self hideIAdBanner:YES];}

// This message will be sent when the user taps on the banner and some action is to be taken.// Actions either display full screen content in a modal session or take the user to a different// application. The delegate may return NO to block the action from taking place, but this// should be avoided if possible because most advertisements pay significantly more when // the action takes place and, over the longer term, repeatedly blocking actions will // decrease the ad inventory available to the application. Applications may wish to pause video, // audio, or other animated content while the advertisement's action executes.- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave;{ return YES;}

// This message is sent when a modal action has completed and control is returned to the application. // Games, media playback, and other activities that were paused in response to the beginning// of the action should resume at this point.- (void)bannerViewActionDidFinish:(ADBannerView *)banner;{ NSLog(@"bannerViewActionDidFinish");}

Tuesday, September 28, 2010

Page 11: iphonedevcon 2010:  Cooking with iAd

Modifying the table view’s frame when an ad

is shown-(CGRect)frameForIAdTable:(BOOL)showingBanner{ CGRect frameForTable = self.view.frame; frameForTable.origin.x = frameForTable.origin.y = 0.0; if (showingBanner) { frameForTable.size.height -= ([self iadBanner].frame.size.height); } return frameForTable;}

Tuesday, September 28, 2010

Page 12: iphonedevcon 2010:  Cooking with iAd

Showing Banner-(void)showIAdBanner:(BOOL)animated{ if (showingIAdBanner) { return; } //resets some of the geometry [self.view addSubview:[self iadBanner]]; [self hideIAdBanner:NO]; if (animated) { [UIView beginAnimations:@"showIAdBanner" context:nil]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; } CGRect frameForTable = [self frameForIAdTable:YES]; [self.tableView setFrame:frameForTable]; CGRect frameForBanner = [[self iadBanner] frame]; frameForBanner.origin.y = frameForTable.size.height; [[self iadBanner] setFrame:frameForBanner]; showingIAdBanner = YES; if (animated) { [UIView commitAnimations]; }}

Tuesday, September 28, 2010

Page 13: iphonedevcon 2010:  Cooking with iAd

Hiding Banner

-(void)hideIAdBanner:(BOOL)animated{ if (animated) { [UIView beginAnimations:@"hideIAdBanner" context:nil]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; } CGRect frameForTable = [self frameForIAdTable:NO]; [self.tableView setFrame:frameForTable]; CGRect frameForBanner = [[self iadBanner] frame]; frameForBanner.origin.y = self.view.frame.size.height + 1; [[self iadBanner] setFrame:frameForBanner]; showingIAdBanner = NO; if (animated) { [UIView commitAnimations]; }}

Tuesday, September 28, 2010

Page 14: iphonedevcon 2010:  Cooking with iAd

#protip

• killall adlibd• ^ for when the simulator doesn’t seem

to want to serve up ads.

Tuesday, September 28, 2010

Page 15: iphonedevcon 2010:  Cooking with iAd

What happens when There is no iAD?

• Internationally (iAD is US only currently)

• Fill rate is meh (ish). • Not available on original phone.• You’ll want a supplemental ad service.

hg updateTuesday, September 28, 2010

Page 16: iphonedevcon 2010:  Cooking with iAd

Mobclix

• http://mobclix.com/• Largest Mobile Ad Exchange• Advertisers Compete for eyeballs• Decent dough

hg update --rev 1 Tuesday, September 28, 2010

Page 17: iphonedevcon 2010:  Cooking with iAd

• Add the Static Library

• Other Linker Flags

• -all_load

• -ObjC

Adding MobClix to Core Data Books

hg updateTuesday, September 28, 2010

Page 18: iphonedevcon 2010:  Cooking with iAd

Adding a Banner#import "AddViewController.h"#import <iAd/iAd.h>#import "MobclixAds.h"

@interface RootViewController : UIViewController <NSFetchedResultsControllerDelegate, AddViewControllerDelegate, ADBannerViewDelegate, MobclixAdViewDelegate> {! NSFetchedResultsController *fetchedResultsController; NSManagedObjectContext *managedObjectContext;! NSManagedObjectContext *addingManagedObjectContext;! ADBannerView *iadBanner; UIView *mobAdBannerHost; MobclixAdView *mobAdBanner; @private BOOL showingIAdBanner; BOOL showingMobAdBanner; BOOL mobAdHasContent;}

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;@property (nonatomic, retain) NSManagedObjectContext *addingManagedObjectContext;@property (nonatomic, retain) IBOutlet UITableView *tableView;@property (nonatomic, retain) ADBannerView *iadBanner;@property(nonatomic, retain)IBOutlet UIView *mobAdBannerHost;@property(nonatomic, retain)IBOutlet MobclixAdView *mobAdBanner;

- (IBAction)addBook;- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;

@endTuesday, September 28, 2010

Page 19: iphonedevcon 2010:  Cooking with iAd

Adding a Banner in IB

Tuesday, September 28, 2010

Page 20: iphonedevcon 2010:  Cooking with iAd

MobClix Delegate Protocol

// Advertisement Status Messages- (void)adViewDidFinishLoad:(MobclixAdView*)adView;{ [self showMobAdBanner:YES]; mobAdHasContent = YES;}- (void)adView:(MobclixAdView*)adView didFailLoadWithError:(NSError*)error;{ [self hideMobAdBanner:YES]; mobAdHasContent = NO;}

// Advertisement Touchthrough Messages- (void)adViewWillTouchThrough:(MobclixAdView*)adView;{

}

- (void)adViewDidFinishTouchThrough:(MobclixAdView*)adView;{

}//- (void)adView:(MobclixAdView*)adView didTouchCustomAdWithString:(NSString*)string;

// Keeps ads from automatically taking over the app.- (BOOL)adViewCanAutoplay:(MobclixAdView*)adView;{ return NO;}

Tuesday, September 28, 2010

Page 21: iphonedevcon 2010:  Cooking with iAd

New stuff in iAD delegate methods

#pragma mark iAD Delegate// This method is invoked each time a banner loads a new advertisement. Once a banner has loaded an ad, // it will display that ad until another ad is available. The delegate might implement this method if // it wished to defer placing the banner in a view hierarchy until the banner has content to display.- (void)bannerViewDidLoadAd:(ADBannerView *)banner;{ [self showIAdBanner:YES]; //give full priority to iAd and get rid of the MobClix ad [self hideMobAdBanner:YES]; [self.mobAdBanner cancelAd]; [self.mobAdBanner pauseAdAutoRefresh];}

// This method will be invoked when an error has occurred attempting to get advertisement content. // Possible error codes defined as constants in ADManager.h.- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error;{ // no iAd adds, so try mobclix [self hideIAdBanner:YES]; [self.mobAdBanner resumeAdAutoRefresh];}

Tuesday, September 28, 2010

Page 22: iphonedevcon 2010:  Cooking with iAd

Modifying the table view’s frame when a Mobclix ad is shown

-(CGRect)frameForMobTable:(BOOL)showingBanner{ CGRect frameForTable = self.view.frame; frameForTable.origin.x = frameForTable.origin.y = 0.0; if (showingBanner) { frameForTable.size.height -= ([self mobAdBannerHost].frame.size.height); } else if (showingIAdBanner) { frameForTable = [self frameForIAdTable:YES]; } return frameForTable;}

Tuesday, September 28, 2010

Page 23: iphonedevcon 2010:  Cooking with iAd

Showing Banner-(void)showMobAdBanner:(BOOL)animated;{ if (showingMobAdBanner) { return; } [self.view addSubview:[self mobAdBannerHost]]; [self hideMobAdBanner:NO]; if (animated) { [UIView beginAnimations:@"showMobAdBanner" context:nil]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; } CGRect frameForTable = [self frameForMobTable:YES]; [self.tableView setFrame:frameForTable]; CGRect frameForBannerHost = [[self mobAdBannerHost] frame]; frameForBannerHost.origin.y = frameForTable.size.height; frameForBannerHost.origin.x = 0.; frameForBannerHost.size.width = self.view.frame.size.width; [[self mobAdBannerHost] setFrame:frameForBannerHost]; CGRect frameForBanner = [self.mobAdBanner frame]; frameForBanner.origin.x = floorf((frameForBannerHost.size.width - self.mobAdBanner.frame.size.width) * .5); frameForBanner.origin.y = 5.; [self.mobAdBanner setFrame:frameForBanner]; showingMobAdBanner = YES; if (animated) { [UIView commitAnimations]; }}

Tuesday, September 28, 2010

Page 24: iphonedevcon 2010:  Cooking with iAd

Hiding Banner

-(void)hideMobAdBanner:(BOOL)animated;{ if (animated) { [UIView beginAnimations:@"hideMobAdBanner" context:nil]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; } CGRect frameForTable = [self frameForMobTable:NO]; [self.tableView setFrame:frameForTable]; CGRect frameForBanner = [[self mobAdBannerHost] frame]; frameForBanner.origin.y = self.view.frame.size.height + 1; [[self mobAdBannerHost] setFrame:frameForBanner]; showingMobAdBanner = NO; if (animated) { [UIView commitAnimations]; }}

Tuesday, September 28, 2010

Page 25: iphonedevcon 2010:  Cooking with iAd

Prettification of mobclix banners

// prettify the mobclix banner a little [[mobAdBanner layer] setBorderColor:[[UIColor grayColor] CGColor]]; [mobAdBannerHost setBackgroundColor:[UIColor colorWithRed:199./255. green:206/255. blue:213/255. alpha:1.]]; CGFloat scale = 1.0; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { scale = [[UIScreen mainScreen] scale]; } if (scale > 1.0) { //iPhone 4 looks okay with border width of one, it's sort of meh on the //lower DPI screens. [[mobAdBanner layer] setBorderWidth:1]; [[mobAdBanner layer] setCornerRadius:4]; } else { [[mobAdBanner layer] setBorderWidth:2]; [[mobAdBanner layer] setCornerRadius:6]; } [mobAdBanner setClipsToBounds:YES]; // Drop shadow below table view (this is an ugly way to do it, but it's easier // in a way given that we support 3.1.2 through 4.0 at this point. UIImage *img = [UIImage imageNamed:@"littleShadow.png"]; CGRect shadowViewFrame = CGRectMake(0, 0, mobAdBannerHost.frame.size.width, img.size.height); UIImageView *shadowView = [[UIImageView alloc] initWithFrame:shadowViewFrame]; [shadowView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [shadowView setImage:img]; [mobAdBannerHost addSubview:shadowView]; [mobAdBannerHost bringSubviewToFront:shadowView]; [shadowView release];

Tuesday, September 28, 2010

Page 26: iphonedevcon 2010:  Cooking with iAd

Rotatin’

• Mobclix ads look awful rotated to landscape• Too tall • Too Narrow

• iAD ads look great in landscape• Hide mobclix no matter what in

landscape

Tuesday, September 28, 2010

Page 27: iphonedevcon 2010:  Cooking with iAd

Rotatin’(heh. Get it? Rotatin?)// Override to allow orientations other than the default portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)

interfaceOrientation {

// Return YES for supported orientations

return (interfaceOrientation == UIInterfaceOrientationPortrait ||

interfaceOrientation == UIDeviceOrientationLandscapeRight ||

interfaceOrientation == UIDeviceOrientationLandscapeLeft);

}

Tuesday, September 28, 2010

Page 28: iphonedevcon 2010:  Cooking with iAd

Rotatin’- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { [self iadBanner].currentContentSizeIdentifier = ADBannerContentSizeIdentifier480x32; if(showingMobAdBanner) { //Admob ads look awful in landscape. They're too big. //Disable them until we can make them pretty [self hideMobAdBanner:YES]; [self.mobAdBanner cancelAd]; [self.mobAdBanner pauseAdAutoRefresh]; } } else { [self iadBanner].currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50; if(!showingIAdBanner) { [self.mobAdBanner resumeAdAutoRefresh]; if (mobAdHasContent) { [self performSelector:@selector(showMobAdBannerAnimated) withObject:nil afterDelay:duration+1]; } } }}

Tuesday, September 28, 2010

Page 29: iphonedevcon 2010:  Cooking with iAd

The End: Questions?

Tuesday, September 28, 2010