Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In-App purchase failing to load list of products

I am trying to implement some inapp purchasing. I have followed the online tutorial and my code is posted below. I have added the in-app purchases to my itunes connect account but when i run the code it calls the 'didfailwitherror' method which is failing to load list of products. Has anyone else had this problem and potentially know a solution?

#import "IAPHelper.h"
#import <StoreKit/StoreKit.h>
NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification";

@interface IAPHelper ()  <SKProductsRequestDelegate, SKPaymentTransactionObserver>

@end

@implementation IAPHelper{
  SKProductsRequest *_productsRequest;
  RequestProductsCompletionHandler _completionHandler;
  NSSet * _productIdentifiers;
  NSMutableSet * _purchasedProductIdentifiers;
}

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

    NSLog(@"get product ids");

if((self=[self init])){
    _productIdentifiers = productIdentifiers;
    _purchasedProductIdentifiers = [NSMutableSet set];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    for (NSString* productIdentifier in _productIdentifiers) {
        NSLog(@"product id is %@", productIdentifier);

        BOOL productPurchased = [[NSUserDefaults standardUserDefaults]    boolForKey:productIdentifier];
        if (productPurchased) {
            [_purchasedProductIdentifiers addObject:productIdentifier];
        }
    }
}
return self;
}

-(void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler{

NSLog(@"Attempt to complete request for products");

  _completionHandler = [completionHandler copy];
  _productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
  _productsRequest.delegate=self;
  [_productsRequest start];
}

#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;

}

- (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];

}

- (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 {
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  int currentHints = [userDefaults integerForKey:@"hintAmount"];
  [_purchasedProductIdentifiers addObject:productIdentifier];
  if ([productIdentifier  isEqual: @"1"]) {
    [userDefaults setInteger:(currentHints+50) forKey:@"hintAmount"];
  }else if ([productIdentifier  isEqual: @"2"]){
    [userDefaults setInteger:(currentHints+100) forKey:@"hintAmount"];
  }else if ([productIdentifier  isEqual: @"3"]){
    [userDefaults setInteger:(currentHints+200) forKey:@"hintAmount"];
  }else if ([productIdentifier  isEqual: @"4"]){
    [userDefaults setInteger:(currentHints+500) forKey:@"hintAmount"];
  }
  [[NSUserDefaults standardUserDefaults] synchronize];
  [[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil];

}


@end
like image 799
Oli Black Avatar asked Nov 02 '22 04:11

Oli Black


1 Answers

FYI - You must run the app on a device to properly get Products for IAPs. I had the issue where it was spitting out all the product identifiers as 'not purchased', but then saying 'Failed to load list of products' when I tried to display them in a table view. This was while running in simulator. Once I ran on a device, worked perfectly!

I used this tutorial to get the basic helper files that do all the heavy lifting: http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial

like image 200
JimmyJammed Avatar answered Nov 14 '22 21:11

JimmyJammed