Reputation: 441
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
Upvotes: 5
Views: 4941
Reputation: 9698
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
Upvotes: 2
Reputation: 3663
Fullfill all condition these are
1.Have you enabled In-App Purchases for your App ID?
2.Have you checked Cleared for Sale for your product?
3.Have you submitted (and optionally rejected) your application binary?
4.Does your project’s .plist Bundle ID match your App ID?
5.Have you generated and installed a new provisioning profile for the new App ID?
6.Have you configured your project to code sign using this new provisioning profile?
7.Are you building for iPhone OS 3.0 or above?
8.Are you using the full product ID when when making an SKProductRequest?
9.Have you waited several hours since adding your product to iTunes Connect?
10.Are your bank details active on iTunes Connect? (via Mark)
11.Have you tried deleting the app from your device and reinstalling?
If you answered “No” to any one of these questions, there’s your problem.
Upvotes: 0