Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving and Remembering In-App Purchases

How do I hide an iAd banner once a non-consumable "Remove Ads" In-App Purchase has been made? I'm not quite sure how to do that or where to do that, according to this tutorial.

Any help would be greatly appreciated!

Thank you

ViewController.h

#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#import <CoreMotion/CoreMotion.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>


@interface ViewController : UIViewController <UIWebViewDelegate, MKMapViewDelegate, CLLocationManagerDelegate>

@property (strong, nonatomic) IBOutlet UIWebView *viewWeb;
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLLocation *currentLocation;
@property (weak, nonatomic) IBOutlet UIImageView *PokeABowlAd;


@end

ViewController.m:

#define SHOW_ADS_KEY @"Show Ads Key"
#define k_Save @"Saveitem"


#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface ViewController () <UITextViewDelegate>


@end

@implementation ViewController

@synthesize viewWeb;

- (void)viewDidLoad {
[super viewDidLoad];

UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backButtonItem];


NSString *fullURL = @"https://www.google.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
viewWeb.scalesPageToFit = YES;
viewWeb.scrollView.bounces = NO;
[viewWeb loadRequest:requestObj];
}

#pragma mark - CLLocationManagerDelegate
// Wait for location callbacks
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}

-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {

if (event.type == UIEventSubtypeMotionShake) {
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"iitc" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];
}
}



- (NSUInteger)supportedInterfaceOrientations {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
    return UIInterfaceOrientationMaskAllButUpsideDown;
} else {
    return UIInterfaceOrientationMaskAll;
}
}


- (IBAction)PokeABowlAd:(id)sender {
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]  isEqualToString: @"No"]){ // NEW CODE
    // Code to show ads
    _PokeABowlAd.hidden = NO;

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://www.pokeabowl.com/"]];
} else {
    _PokeABowlAd.hidden = YES;
}
NSLog(@"Shows ads?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]);

}

- (void)viewWillAppear {
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY] isEqualToString: @"No"]){ // NEW CODE
    // Code to show ads
    _PokeABowlAd.hidden = NO;

} else {
    _PokeABowlAd.hidden = YES;
}
NSLog(@"Shows ads?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]);
}


@end

MasterViewController.m:

    #import "MasterViewController.h"
#import "DetailViewController.h"
#import "RageIAPHelper.h"
#import <StoreKit/StoreKit.h>

@interface MasterViewController () {
NSArray *_products;
NSNumberFormatter * _priceFormatter;
}
@end

@implementation MasterViewController

- (void)viewDidLoad
{
[super viewDidLoad];

UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backButtonItem];

self.title = @"Settings";

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(reload) forControlEvents:UIControlEventValueChanged];
[self reload];
[self.refreshControl beginRefreshing];

_priceFormatter = [[NSNumberFormatter alloc] init];
[_priceFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[_priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Restore" style:UIBarButtonItemStylePlain target:self action:@selector(restoreTapped:)];

}

- (void)restoreTapped:(id)sender {
[[RageIAPHelper sharedInstance] restoreCompletedTransactions];
}

- (void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:) name:IAPHelperProductPurchasedNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)productPurchased:(NSNotification *)notification {

NSString * productIdentifier = notification.object;
[_products enumerateObjectsUsingBlock:^(SKProduct * product, NSUInteger idx, BOOL *stop) {
    if ([product.productIdentifier isEqualToString:productIdentifier]) {
        [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
        *stop = YES;
    }
}];

}

- (void)reload {
_products = nil;
[self.tableView reloadData];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
    if (success) {
        _products = products;
        [self.tableView reloadData];
    }
    [self.refreshControl endRefreshing];
}];
}

#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _products.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

SKProduct * product = (SKProduct *) _products[indexPath.row];
cell.textLabel.text = product.localizedTitle;
[_priceFormatter setLocale:product.priceLocale];
cell.detailTextLabel.text = [_priceFormatter stringFromNumber:product.price];

if ([[RageIAPHelper sharedInstance] productPurchased:product.productIdentifier]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    cell.accessoryView = nil;
} else {
    UIButton *buyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    buyButton.frame = CGRectMake(0, 0, 72, 37);
    [buyButton setTitle:@"Buy" forState:UIControlStateNormal];
    buyButton.tag = indexPath.row;
    [buyButton addTarget:self action:@selector(buyButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.accessoryView = buyButton;
}

return cell;
}

- (void)buyButtonTapped:(id)sender {

UIButton *buyButton = (UIButton *)sender;
SKProduct *product = _products[buyButton.tag];

NSLog(@"Buying %@...", product.productIdentifier);
[[RageIAPHelper sharedInstance] buyProduct:product];

}

@end

IAPHelper.h:

    #import <StoreKit/StoreKit.h>


UIKIT_EXTERN NSString *const IAPHelperProductPurchasedNotification;

typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);

@interface IAPHelper : NSObject

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers;
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler;
- (void)buyProduct:(SKProduct *)product;
- (BOOL)productPurchased:(NSString *)productIdentifier;
- (void)restoreCompletedTransactions;
@property (weak, nonatomic) IBOutlet UIImageView *PokeABowlAd;

@end

IAPHelper.m:

    #define SHOW_ADS_KEY @"Show Ads Key"

// 1
#import "IAPHelper.h"
#import <StoreKit/StoreKit.h>

NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification";

// 2
@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end

// 3
@implementation IAPHelper {
SKProductsRequest * _productsRequest;
RequestProductsCompletionHandler _completionHandler;

NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
}




- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {

if ((self = [super init])) {

    // Store product identifiers
    _productIdentifiers = productIdentifiers;

    // Check for previously purchased products
    _purchasedProductIdentifiers = [NSMutableSet set];
    for (NSString * productIdentifier in _productIdentifiers) {
        BOOL productPurchased = [[NSUserDefaults standardUserDefaults]     boolForKey:productIdentifier];
        if (productPurchased) {
            [_purchasedProductIdentifiers addObject:productIdentifier];
            NSLog(@"Previously purchased: %@", productIdentifier);
            // NEW CODE
            if ([productIdentifier isEqualToString:@"Ads"]){
                [[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:SHOW_ADS_KEY];
                [[NSUserDefaults standardUserDefaults] synchronize];
            }
            // NEW CODE ^^

        } else {
            NSLog(@"Not purchased: %@", productIdentifier);
        }
    }

    // Add self as transaction observer
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}


- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {


// 1
_completionHandler = [completionHandler copy];

// 2
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];

}

- (BOOL)productPurchased:(NSString *)productIdentifier {
return [_purchasedProductIdentifiers containsObject:productIdentifier];
}

- (void)buyProduct:(SKProduct *)product {

NSLog(@"Buying %@...", product.productIdentifier);

SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];

}

#pragma mark - SKProductsRequestDelegate

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

NSLog(@"Loaded list of products...");
_productsRequest = nil;

NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
    NSLog(@"Found product: %@ %@ %0.2f",
          skProduct.productIdentifier,
          skProduct.localizedTitle,
          skProduct.price.floatValue);
}

_completionHandler(YES, skProducts);
_completionHandler = nil;

}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {

NSLog(@"Failed to load list of products.");
_productsRequest = nil;

_completionHandler(NO, nil);
_completionHandler = nil;

}

#pragma mark SKPaymentTransactionOBserver

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
    switch (transaction.transactionState)
    {
        case SKPaymentTransactionStatePurchased:
            [self completeTransaction:transaction];
            break;
        case SKPaymentTransactionStateFailed:
            [self failedTransaction:transaction];
            break;
        case SKPaymentTransactionStateRestored:
            [self restoreTransaction:transaction];
        default:
            break;
    }
};
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");

[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"restoreTransaction...");

[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

- (void)failedTransaction:(SKPaymentTransaction *)transaction {

NSLog(@"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
{
    NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
}

[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {

[_purchasedProductIdentifiers addObject:productIdentifier];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil];

}

- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

@end

RageIAPHelper.h

    #import "IAPHelper.h"

@interface RageIAPHelper : IAPHelper

+ (RageIAPHelper *)sharedInstance;

@end

RageIAPHelper.m

    #import "RageIAPHelper.h"
#import "ViewController.h"

@implementation RageIAPHelper

+ (RageIAPHelper *)sharedInstance {
static dispatch_once_t once;
static RageIAPHelper * sharedInstance;
dispatch_once(&once, ^{
    NSSet * productIdentifiers = [NSSet setWithObjects:
                                  @“com.GPS.iapra",
                                  @"com.GPS.iapb”,
                                  nil];
    sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers];
});
return sharedInstance;
}

@end
like image 327
Creagen Avatar asked Mar 15 '23 02:03

Creagen


1 Answers

You should NSUserDefaults.

Put at the top of both .m files:

#define SHOW_ADS_KEY @"Show Ads Key"

When the user has purchased the IAP you do this (in IAP.m):

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {

if ((self = [super init])) {

    // Store product identifiers
    _productIdentifiers = productIdentifiers;

    // Check for previously purchased products
    _purchasedProductIdentifiers = [NSMutableSet set];
    for (NSString * productIdentifier in _productIdentifiers) {
        BOOL productPurchased = [[NSUserDefaults standardUserDefaults]     boolForKey:productIdentifier];
        if (productPurchased) {
            [_purchasedProductIdentifiers addObject:productIdentifier];
            NSLog(@"Previously purchased: %@", productIdentifier);
// NEW CODE
if ([productIdentifier isEqualToString:@"com.GPS.iapra"]){
         [[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:SHOW_ADS_KEY];
         [[NSUserDefaults standardUserDefaults] synchronize];
        }
// NEW CODE ^^

        } else {
            NSLog(@"Not purchased: %@", productIdentifier);
        }
    }

    // Add self as transaction observer
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

}

For the ad code (in VC.m):

- (void)viewWillAppear { 
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY] isEqualToString: @"No"]){ // NEW CODE
      // Code to show ads
      PokeABowlAd.hidden = NO;

   } else {
      PokeABowlAd.hidden = YES;
   }
NSLog(@"Shows ads?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]); 
}

Now modify completeTransaction:

- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");

if ([transaction.payment.productIdentifier isEqualToString:@"com.GPS.iapra"]){
             [[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:SHOW_ADS_KEY];
             [[NSUserDefaults standardUserDefaults] synchronize];
            }

[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
like image 152
Wyetro Avatar answered Mar 19 '23 08:03

Wyetro