I have created a nonconsumable in app purchase item and now I want to create a consumable in-app purchase by which a user to buy it every time he uses it,and also I want to create a subscription model In-App purchase. Everything works as expected except when I buy the item more than one time, iPhone pop ups a message saying "You've already purchased the item. Do You want to buy it again?". Is It possible to disable this dialog and proceed to the actual purchase?And what will have to change in following code with different model:-
in InApp purchase manager.m:
@implementation InAppPurchaseManager
//@synthesize purchasableObjects;
//@synthesize storeObserver;
@synthesize proUpgradeProduct;
@synthesize productsRequest;
//BOOL featureAPurchased;
//BOOL featureBPurchased;
//static InAppPurchaseManager* _sharedStoreManager; // self
(void)dealloc {
//[_sharedStoreManager release];
//[storeObserver release];
[super dealloc];
}
(void)requestProUpgradeProductData
{
NSSet *productIdentifiers = [NSSet setWithObject:@"com.vigyaapan.iWorkOut1" ];
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
// we will release the request object in the delegate callback
}
pragma mark -
pragma mark SKProductsRequestDelegate methods
(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
//NSArray *products = response.products;
//proUpgradeProduct = [products count] == 1 ? [[products firstObject] retain]: nil;
if (proUpgradeProduct)
{
NSLog(@"Product title: %@", proUpgradeProduct.localizedTitle);
NSLog(@"Product description: %@", proUpgradeProduct.localizedDescription);
NSLog(@"Product price: %@", proUpgradeProduct.price);
NSLog(@"Product id:%@", proUpgradeProduct.productIdentifier);
}
/*for (NSString invalidProductId in response.invalidProductIdentifiers)
{
NSLog(@"Invalid product id: %@" , invalidProductId);
}/
//finally release the reqest we alloc/init’ed in requestProUpgradeProductData
[productsRequest release];
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
}
pragma -
pragma Public methods
/* call this method once on startup*/
(void)loadStore
{
/* restarts any purchases if they were interrupted last time the app was open*/
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
/* get the product description (defined in early sections)*/
[self requestProUpgradeProductData];
}
/* call this before making a purchase*/
(BOOL)canMakePurchases
{
return [SKPaymentQueue canMakePayments];
}
/* kick off the upgrade transaction*/
(void)purchaseProUpgrade
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"9820091347"];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
pragma -
pragma Purchase helpers
/* saves a record of the transaction by storing the receipt to disk*/
(void)recordTransaction:(SKPaymentTransaction )transaction
{
if ([transaction.payment.productIdentifier isEqualToString:kInAppPurchaseProUpgradeProductId])
{
/ save the transaction receipt to disk*/
[[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"proUpgradeTransactionReceipt" ];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
/* enable pro features*/
(void)provideContent:(NSString )productId
{
if ([productId isEqualToString:kInAppPurchaseProUpgradeProductId])
{
/ enable the pro features*/
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isProUpgradePurchased" ];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
(void)finishTransaction:(SKPaymentTransaction )transaction wasSuccessful:(BOOL)wasSuccessful
{
// / remove the transaction from the payment queue.*/
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
if (wasSuccessful)
{
/* send out a notification that we’ve finished the transaction*/
[[NSNotificationCenter defaultCenter]postNotificationName:kInAppPurchaseManagerTransactionSucceededNotification
object:self userInfo:userInfo];
}
else
{
/* send out a notification for the failed transaction*/
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
}
}
(void)completeTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
(void)restoreTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction.originalTransaction];
[self provideContent:transaction.originalTransaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
(void)failedTransaction:(SKPaymentTransaction )transaction
{
if (transaction.error.code != SKErrorPaymentCancelled)
{
/ error!/
[self finishTransaction:transaction wasSuccessful:NO];
}
else
{
/ this is fine, the user just cancelled, so don’t notify*/
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
(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];
break;
default:
break;
}
}
}
@end
in SKProduct.m:-
@implementation SKProduct (LocalizedPrice)
- (NSString *)localizedPrice
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:self.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:self.price];
[numberFormatter release];
return formattedString;
}