I followed this tutorial to help me add in-app purchases. It works well, except now I am trying to add another non-consumable IAP. I defined my second product ID and created a method for the purchase button, but I'm not sure if I have to create another SKProductsRequest for this extra item, or if I use the same one, etc...
Here is my full code.
#define kRemoveAdsProductIdentifier #"099"
#define kDoubleEarningRateProductIdentifer #"199"
- (void)removeAds{
NSLog(#"User requests to remove ads");
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kRemoveAdsProductIdentifier]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)doubleEarningRate{
NSLog(#"User requests 2x earning rate");
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kDoubleEarningRateProductIdentifer]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
validProduct = [response.products objectAtIndex:0];
NSLog(#"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(#"No products available");
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (void)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void) restore{
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
if(SKPaymentTransactionStateRestored){
NSLog(#"Transaction state -> Restored");
//called when the user successfully restores a purchase
[self doRemoveAds];
[self doubleEarningRate];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(#"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
[self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction state -> Purchased");
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finnish
if(transaction.error.code != SKErrorPaymentCancelled){
NSLog(#"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
-(void)doRemoveAds
{
areAdsRemoved = true;
NSLog(#"Ads Removed");
[topBanner removeFromSuperview];
}
-(void)doDoubleEarningRate
{
}
I also read through apple documentation which explained to me what each part does, but I am still clueless on how I can add another purchase, and most other tutorials are done differently or outdated. Also all the variables and indirection is a bit intimidating to me. So I am hoping that someone can give me a quick step by step guide for adding another purchase.
To make it clearer, this approach works perfectly for just one in app purchase. However I don't know how to add more, as in I don't know how to make the program recognize which in-app purchase is being selected.
Thanks.
I fixed this by creating a method called provideContent:(NSString *)productId. Then you can either use a switch statement or if statement to differentiate between product Id's. No need to create multiple types of productRequest methods, etc...
Related
Hopefully this is enough information to help me solve my problem.
I am setting up In App Purchases via a templated source code that was given to me. In my MKStoreManager.m file, where I set up the featureID's for my in app purchases (Ex: static NSString *featureAId = #"com.logannat.myfirstgameTier1";)
When clicking on the actual button in the game, a method
- (void) buyFeature:(SKProduct*) product
{
if ([SKPaymentQueue canMakePayments])
{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
}
ends up getting called. I set a break point, and found the error to be in the last line of that code.
The variables that show up in the break point state are:
self = (MKStoreManager *)"reference number"
product = (SKProduct *) nil
and
payment = (SKPayment *) "reference number"
I can not seem to figure out what the problem is here. Any help would be much appreciated, thank you.
i do not have swift Right now so i am giving you Xcode code please convert the syntax accordingly its not so difficult.
so here is the complete life cycle for the in app purchased.
in your header file call these delegates and setup the bool for checking the status of you purchased
like that
#import <UIKit/UIKit.h>
BOOL arefavorite_access;
BOOL areAdsRemoved;
#interface ViewController : UIViewController<SKProductsRequestDelegate, SKPaymentTransactionObserver>{
}
- (IBAction)purchase;
- (IBAction)restore;
- (IBAction)tapsRemoveAds:(id)sender;
#end
one you need to hockup this tapsRemoveAds method on touchupinside of you button selector ant it will start working.
- (IBAction)tapsRemoveAds:(id)sender{
UIButton*btn=(UIButton*)sender;
NSString *featureAId = #"com.logannat.myfirstgameTier1";
NSLog(#"User requests to remove ads");
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest;
if (btn.tag==1) {
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject: featureAId]];
_protype= featureAId;
}
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
product request method
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
validProduct = [response.products objectAtIndex:0];
NSLog(#"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(#"No products available");
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (IBAction)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction) restore{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
NSLog(#"%#",queue );
NSLog(#"Restored Transactions are once again in Queue for purchasing %#",[queue transactions]);
NSMutableArray *purchasedItemIDs = [[NSMutableArray alloc] init];
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions) {
NSString *productID = transaction.payment.productIdentifier;
[purchasedItemIDs addObject:productID];
NSLog (#"product id is %#" , productID);
_protype=productID;
[self doRemoveAds];
// here put an if/then statement to write files based on previously purchased items
// example if ([productID isEqualToString: #"youruniqueproductidentifier]){write files} else { nslog sorry}
}
if(queue.transactions.count==0){
[Utilities showOKAlertWithTitle:#"Restore purchase" message:#"you have no product available for restoration"];
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch(transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(#"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
[self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction state -> Purchased");
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction state -> Restored");
_protype=transaction.payment.productIdentifier;
[self doRemoveAds];
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finish
if(transaction.error.code == SKErrorPaymentCancelled){
NSLog(#"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
break;
}
}
}
- (void)doRemoveAds{
// // [self.bannerView setAlpha:0];
NSString *featureAId = #"com.logannat.myfirstgameTier1";
NSString *featureAIdnumber2 = #"com.logannat.myfirstgameTier2";
if([_protype isEqualToString:featureAId]){
arefavorite_access = YES;
[[NSUserDefaults standardUserDefaults] setBool:arefavorite_access forKey:frareFavoriteRemoved];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else if([_protype isEqualToString: featureAIdnumber2]){
areAdsRemoved = YES;
[[NSUserDefaults standardUserDefaults] setBool:areAdsRemoved forKey:frareAdsRemoved];
[[NSUserDefaults standardUserDefaults] synchronize];
}
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
// [self showpopUp:self];
}
if this answer helps you please vote up and accept the answer
We have been rejected by review team recently for a In-App Purchase issue.
We discovered one or more bugs in your app when reviewed on iPhone
running iOS 8.2 on both Wi-Fi and cellular networks.
Specifically,
your application’s In App Purchase Transaction cannot be completed.
The steps to reproduce are:
Launch app
Navigate to purchase/recharge tab
Proceed to purchase one of the In-App Purchase products
In-App Purchase confirmation window appears
Confirm purchase
In-App Purchase results in an error
BUT! In-App Purchase runs well in sandbox! We checked log on our server, but we can't find any receipt verification logs. It seems that purchase completion window didn't appear at all.
We found we would use the following code sometimes:
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
Is that the ONLY reason? T.T
EDIT:
We had released several versions before. This time we added a new product. But we forgot to add its identifier to the following array.
-(void)requestProducts
{
if (_products) {
return;
}
NSSet* identifiers = [NSSet setWithObjects:
#"identifier",
#"new identifier", // forgot this line
nil];
SKProductsRequest* _request = [[SKProductsRequest alloc] initWithProductIdentifiers:identifiers];
_request.delegate = self;
[_request start];
_requestProcessing = YES;
}
So the following code will return nil:
-(SKProduct*)getProduct:(NSString *)identifier
{
if (_products) {
for (SKProduct* product in _products) {
if ([product.productIdentifier isEqualToString:identifier]) {
return product;
}
}
} else if (!_requestProcessing) {
[self requestProducts];
}
return nil;
}
When user buy a product:
-(void)buyProductIdentifier:(NSString *)productIdentifier
{
if (![self isNetworkOK] || ![SKPaymentQueue canMakePayments]) {
[[NSNotificationCenter defaultCenter] postNotificationName:NotifyPurchaseFailed object:productIdentifier];
return;
}
NSLog(#"Buying %#...", productIdentifier);
SKProduct* product = [self getProduct:productIdentifier];
if (product) { // the new identifier gets nil here
SKPayment* payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
} else { // calls the deprecated api
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
}
BUT, it runs well in sandbox.
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed: // may break here
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
}
Any idea? All the products on itunes connect are in Approved state except the new one. The new product is in Waiting for Review state.
I am working on IAP first time. I have created test user and working good in sandbox env. I can see my Purchase and buy it as well(And of course i added StoreKit framework.), but problem is that: when i upload update with IAP to AppStore - moderator has reject my app, here is a reason:
We found that while you have submitted In App Purchase products for your app, the In App Purchase functionality is not present in your binary. Please see the attached screenshot/s for more information.(there is no some Purchase on the screen, empty space instead)
If you would like to utilize In App Purchase in your app, you will need to upload a new binary that incorporates the In App Purchase API to enable users to make a purchase
I just don't understand how it's possible? Why when i testing IAP - it's works fine, but it doesn't work when moderator doing it? All IAP have "Cleared for Sale" and "Waiting for review" status
Now if i upload app to the store will IAP works? Or maybe i need to do some additional action before?
Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
_iapArray = [[NSMutableArray alloc] init];
iap1 = #"com.mypurchase.addcoins1";
[self paymentCheck];
}
- (void)viewDidDisappear:(BOOL)animated
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
- (void)paymentCheck{
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:iap1, nil]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
_iapArray = response.products;
indicator.hidden = YES;
[self.tableView reloadData];
}
else if(!validProduct){
NSLog(#"No products available");
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Error"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[myAlertView show];
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (IBAction)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(#"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
// [self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction state -> Purchased - %#", transaction.payment.productIdentifier);
if ([transaction.payment.productIdentifier isEqualToString:iap1]) {
[self addCoins:5];
}
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finnish
if(transaction.error.code != SKErrorPaymentCancelled){
NSLog(#"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
As per their reply, you have integrated IAP in application but you have not used it. So, can you please make sure you have properly integrated IAP in application ? Please test in same Device and iOS if they mentioned.
I used info from this brilliant page to add in-app purchases.
However I get the NSLog No Product Available. I have checked to make sure I have added the correct Product ID. I am at a loss to what to do and have been at this for several hours.
This is for a game built on Cocos2d and I can't figure out what is wrong. Sorry for the abundance of code.
I have added <SKProductsRequestDelegate, SKPaymentTransactionObserver> and <StoreKit/StoreKit.h>
.m
#define kRemoveAdsProductIdentifier #"COINS1000"
#implementation shopCoins
- (void)buy500Coins{
NSLog(#"User requests to remove ads");
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kRemoveAdsProductIdentifier]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
validProduct = [response.products objectAtIndex:0];
NSLog(#"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(#"No products available");
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (IBAction)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction) restore{
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
if(SKPaymentTransactionStateRestored){
NSLog(#"Transaction state -> Restored");
//called when the user successfully restores a purchase
[self doRemoveAds];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(#"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
[self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction state -> Purchased");
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finnish
if(transaction.error.code != SKErrorPaymentCancelled){
NSLog(#"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)doRemoveAds{
NSLog(#"Bitches");
}
If it's a debug build you probably need to add a sandbox user on iTunes connect this will allow you to use IAP that have not been reviewed yet. Note this user should match your iTunes connect account.
this has been driving me crazy but I'm trying to have an in-app purchase to remove iAds. my app is complete except for this one part and i cant for the life of me figure out how to do this. Ive added the iAds to the app already by means of using the iAd banner in the storyboard then adding the code
-(void)bannerViewDidLoadAd:(ADBannerView *)banner {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[banner setAlpha:1];
[UIView commitAnimations];
}
- (void)bannerView:(ADBannerView *) banner didFailToReceiveAdWithError:error{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[banner setAlpha:0];
[UIView commitAnimations];
}
in my .m, the iAd works in my simulator but I'm wanting to have a in-app purchase to remove these. I've already gone through the process in iTunes connect to allow this but i cant figure out the coding in Xcode needed to implement this
ive tried implementing this
#define kRemoveAdsProductIdentifier #"put your product id (the one that we just made in iTunesConnect) in here"
- (void)tapsRemoveAds{
NSLog(#"User requests to remove ads");
if([SKPaymentQueue canMakePayments]){
NSLog(#"User can make payments");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kRemoveAdsProductIdentifier]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(#"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
validProduct = [response.products objectAtIndex:0];
NSLog(#"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(#"No products available");
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (IBAction)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction) restore{
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
if(SKPaymentTransactionStateRestored){
NSLog(#"Transaction state -> Restored");
//called when the user successfully restores a purchase
[self doRemoveAds];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(#"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
[self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction state -> Purchased");
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finnish
if(transaction.error.code != SKErrorPaymentCancelled){
NSLog(#"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
You need to check whether the user has bought the IAP. If he has done it, remove the iAd view (or setAlpha = 0)
UPDATE
The moment the user completes payment (where you receive SKPaymentTransactionStatePurchased / SKPaymentTransactionStateRestored, save a flag into NSUserDefaults, so that you will know whether the user has bought the IAP, and show/hide the iAd correspondingly.
If there is nothing in NSUserDefaults, that means: (1) user hasn't bought the IAP OR (2) user has bought it but somehow the info has been lost in NSUserDefaults (e.g. user deleted & reinstalled the app). In either case, the right way to go is to ask the user to buy the IAP. If (2) happens, App Store will automatically restore the IAP, and you will receive a SKPaymentTransactionStateRestored. The code for SKPaymentTransactionStateRestored and SKPaymentTransactionStatePurchased should be similar: setting NSUserDefaults flag.
To avoid confusion, some apps provide a Restore button, which calls [SKPaymentQueue restoreCompletedTransactions] and generate SKPaymentTransactionStateRestored if some IAP has been bought by user. This does nothing if the user hasn't bought any IAP.