I successfully implemented an in-app purchase to remove ads in my app. It worked the first time I tried it but after I ran the app on my phone a few more times it started to just show a white ad banner instead of hidding the ad banner like it used to.
Here is the code for the StartScreen.m of my app as well as the PurchaseViewController.m to buy the IAP to remove ads. I also got a Warning saying I am using 10 instances of ADBanner even though I have them removed whenever the view disappers. Thank you for any and all help.
//
//StartScreen.m
//
@interface StartScreen ()
{
BOOL _bannerIsVisible;
}
@end
@implementation StartScreen
- (void)viewDidLoad {
//Ads
self.adBanner.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.adBanner removeFromSuperview];
self.adBanner.delegate = nil;
self.adBanner = nil;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
// Check for Remove Ads IAP
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([prefs boolForKey:@"RemoveAds"] == TRUE) {
self.adBanner.hidden = YES;
_bannerIsVisible = NO;
} else if (!_bannerIsVisible)
{
self.adBanner.hidden = NO;
_bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
NSLog(@"Failed to retreive ad");
// Check for Remove Ads IAP
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([prefs boolForKey:@"RemoveAds"] == TRUE) {
self.adBanner.hidden = YES;
_bannerIsVisible = NO;
}
}
//
// PurcahseViewController.m
//
#import "PurcahseViewController.h"
@implementation PurcahseViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.productID = @"com.app.iap1";
[self getProductID:self];
self.buyButton.enabled = NO;
NSLog(@"%@", self.productID);
}
- (void)getProductID:(UIViewController *)viewController {
if ([SKPaymentQueue canMakePayments]) {
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:self.productID]];
request.delegate = self;
[request start];
} else {
self.productDescription.text = @"Please enable in app purchase in your settings";
}
}
- (IBAction)purchaseItem:(id)sender {
SKPayment *payment = [SKPayment paymentWithProduct:self.product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction)restoreButton:(id)sender {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
[self UnlockPurchase];
}
- (void)Purchased {
NSLog(@"Item has been purchased");
}
#pragma mark _
#pragma mark SKProductsRequestDelegate
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSArray *products = response.products;
if (products.count != 0) {
self.product = products[0];
self.buyButton.enabled = YES;
self.productTitle.text = self.product.localizedTitle;
self.productDescription.text = self.product.localizedDescription;
} else {
self.productTitle.text = @"404: Product Not Found";
}
products = response.invalidProductIdentifiers;
for (SKProduct *product in products) {
NSLog(@"404: Product Not Found: %@", product);
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: [self UnlockPurchase];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:NSLog(@"Transaction Failed");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
default:
break;
}
}
}
-(void)UnlockPurchase {
self.buyButton.enabled = NO;
[self.buyButton setTitle:@"Purchased" forState:UIControlStateDisabled];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setBool:TRUE forKey:@"RemoveAds"];
[prefs synchronize];
[self Purchased];
}
First off, to answer your question, the reason your banner isn't hiding when your ad fails is because you're not hiding it. Whether or not
[prefs boolForKey:@"RemoveAds"] == TRUE
, you're going to want to hide that banner if you don't want the blank white bar in its place. To do so in the simplest possible way (without any animation), simplify yourdidFailToReceiveAdWithError:
method, like so:And hide it in your
viewDidLoad
so it's hidden from the very beginning before any ad has loaded:That way, your ad will only unhide in
bannerViewDidLoadAd:
once an ad has successfully been loaded.Secondly, your
_bannerIsVisible
boolean is unnecessary. Instead of using a separate boolean to check whether the banner is visible, you can just check whether it's hidden, withif (self.adBanner.hidden == YES)
orif (self.adBanner.hidden == NO)
orif (self.adBanner.hidden)
orif (!self.adBanner.hidden)
. Eliminating that unnecessary boolean will cut down on the potential for error.So, just to summarize, here's my suggestion for how your
bannerViewDidLoadAd:
anddidFailToReceiveAdWithError:
methods should look: