使用IBAction /button进行应用程序内购买

我使用Ray Wenderlich教程来创buildIAP(http://www.raywenderlich.com/23266/),一切正常,但我不想在我的应用程序上使用表视图,我只想使用简单IBActionbutton进行购买。

所以基本上这是它在桌面视图上的工作方式。 首先确定产品:

+ (RageIAPHelper *)sharedInstance { static dispatch_once_t once; static RageIAPHelper * sharedInstance; dispatch_once(&once, ^{ NSSet * productIdentifiers = [NSSet setWithObjects: @"com.companyname.10coins", @"com.companyname.20coins", nil]; sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers]; }); return sharedInstance; } 

然后触发行动:

  - (void)buyButtonTapped:(id)sender { UIButton *buyButton = (UIButton *)sender; SKProduct *product = _products[buyButton.tag]; NSLog(@"Buying %@...", product.productIdentifier); [[RageIAPHelper sharedInstance] buyProduct:product]; } - (void)buyProduct:(SKProduct *)product { NSLog(@"Buying %@...", product.productIdentifier); SKPayment * payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } 

所以我试图做一个简单的button来触发行动,像这样:

  - (IBAction)button10Coins:(id)sender { SKPayment * payment = [SKPayment paymentWithProduct:@"com.companyname.10coins"]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } 

但是我得到一个警告“不兼容的指针types”。

开始之后,代码运行良好,我可以完成购买,唯一的问题是正确创buildIBAction。 有任何想法吗?

谢谢!!!

如果你已经完成了所有的连接工作,并且添加下面的代码框架,那么肯定会工作:

定义kStoredData @“inapp购买的对象”(这是对象声明)

 - (void) requestProductData { if(countphotoval==2) { phonetext.text=@""; countrycode.text=@""; nametext.text=@""; Emailtext.text=@""; photocounter=0; image1.image=[UIImage imageNamed:@"image-box.png"]; image2.image=[UIImage imageNamed:@"image-box.png"]; labelimage.text=@"Image"; addbuttonforpicker.userInteractionEnabled=true; addbuttonforpicker2.userInteractionEnabled=false; countphotoval=0; } request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: @"object of inapp purchase"]]; request.delegate = self; [request start]; } - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSArray *myProduct = response.products; // populate UI } -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { NSLog(@"transaction array-->%@",transaction.description); switch (transaction.transactionState) { case SKPaymentTransactionStatePurchasing: // show wait view here //statusLabel.text = @"Processing..."; break; case SKPaymentTransactionStatePurchased: [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; [NSThread detachNewThreadSelector:@selector(startActivityindicatore) toTarget:self withObject:nil]; [self fordataupload]; break; case SKPaymentTransactionStateRestored: [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; break; case SKPaymentTransactionStateFailed: if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"Error payment cancelled"); UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Sorry" message:@"Please provide correct Userid and Password" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil]; [alert show]; [alert release]; // [self dismissModalViewControllerAnimated:YES]; } [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; // remove wait view here // statusLabel.text = @"Purchase Error!"; break; default: break; } } } - (void) failedTransaction: (SKPaymentTransaction *)transaction { if (transaction.error.code != SKErrorPaymentCancelled) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Something has went wrong" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void) restoreTransaction: (SKPaymentTransaction *)transaction { //If you want to save the transaction // [self recordTransaction: transaction]; //Provide the new content // [self provideContent: transaction.originalTransaction.payment.productIdentifier]; //Finish the transaction [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void) completeTransaction: (SKPaymentTransaction *)transaction { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Congrats!!" message:@"Your Transaction Is Completed" delegate:self cancelButtonTitle:@"Thanx!" otherButtonTitles:nil]; [alert show]; [alert release]; //If you want to save the transaction // [self recordTransaction: transaction]; //Provide the new content //[self provideContent: transaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } -(void)requestDidFinish:(SKRequest *)request1 { [self stopActivityindicatore]; SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"VirtualBinocularsContest1"]; NSLog(@"quality --->%d",payment.quantity); [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [[SKPaymentQueue defaultQueue] addPayment:payment]; [request release]; } 

请通知,如果它适合你.. 🙂

paymentWithProduct:期望一个SKProduct *参数,并传递一个NSString 。 您需要将您的产品从_products数组中取出,然后传递。

感谢所有帮助我的人! 我终于做到了。

我出来了一个不同的代码。 我会尽力解释我在这里所做的一切,如果有人想这样做。

先在iOS Provisioning Portal上创buildApp ID,然后在iTunes Connect上创buildIAP Purchase。

然后,得到这个项目: http ://xcodenoobies.blogspot.com.br/2012/04/implementing-inapp-purchase-in-xcode.html并导入“SFHFKeychainUtils.h”和.m文件。 不要忘记将SFHFKeychainUtils.m添加到您的编译源(项目 – >构build阶段 – >编译源)。

现在代码:

。H

 #import <StoreKit/StoreKit.h> (...) <SKProductsRequestDelegate, SKPaymentTransactionObserver, UIAlertViewDelegate> { IBOutlet UIButton *feature2Btn; IBOutlet UILabel *featureLabel, *statusLabel; UIAlertView *askToPurchase; int64_t coins; IBOutlet UILabel * coinsLabel; } @property (nonatomic, retain) UIButton *feature2Btn; @property (nonatomic, retain) UILabel *featureLabel, *statusLabel; @property (nonatomic, assign) int64_t coins; -(IBAction)button10Coins:(id)sender; -(BOOL)IAPItemPurchased; 

.M

 #import "SFHFKeychainUtils.h" @synthesize feature2Btn, featureLabel, statusLabel, coins; #define kStoredData @"com.IAPID.10coins" 

button:

 -(IBAction)button10Coins:(id)sender { askToPurchase = [[UIAlertView alloc] initWithTitle:@"IAP" message:@"Would you like to buy 10 coins?" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Yes", @"No", nil]; askToPurchase.delegate = self; [askToPurchase show]; } 

检查IAP是否可用:

 #pragma mark AlertView Delegate -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView==askToPurchase) { if (buttonIndex==0) { // user tapped YES, but we need to check if IAP is enabled or not. if ([SKPaymentQueue canMakePayments]) { NSLog(@"IAP: Checking if IAP Available"); SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.IAPID.10coins"]]; request.delegate = self; [request start]; } else { UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:@"Prohibited" message:@"Parental Control is enabled, cannot make a purchase!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil]; [tmp show]; } } } } 

请求产品(如果有的话),或者如果没有的话取消购买:

 -(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSLog(@"IAP: Received Response"); // remove wait view here statusLabel.text = @""; SKProduct *validProduct = nil; int count = [response.products count]; if (count>0) { NSLog(@"IAP: Available, starting transaction"); validProduct = [response.products objectAtIndex:0]; SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.IAPID.10coins"]; [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } else { NSLog(@"IAP: Item not found"); UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:@"Internet Connection Required" message:@"You must connect to a Wi-Fi or cellular data network to perform an In-App Purchase." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil]; [tmp show]; } } 

最后,行动:

 #pragma mark StoreKit Delegate -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchasing: { // show wait view here NSLog(@"IAP: Processing...");} break; case SKPaymentTransactionStatePurchased:{ [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; // remove wait view and unlock feature 2 statusLabel.text = @"Done!"; UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:@"Completet" message:@"The purchase has been completed!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil]; [tmp show]; NSError *error = nil; [SFHFKeychainUtils storeUsername:@"IAPNoob01" andPassword:@"whatever" forServiceName:kStoredData updateExisting:YES error:&error]; // apply purchase action - hide lock overlay and [feature2Btn setBackgroundImage:nil forState:UIControlStateNormal]; // Get The Coins, rock, favor points, whatever: self.coins = coins +10; coinsLabel.text = [NSString stringWithFormat: @"%lld", self.coins]; } break; case SKPaymentTransactionStateRestored:{ [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; // remove wait view here statusLabel.text = @"";} break; case SKPaymentTransactionStateFailed:{ if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"Error payment cancelled"); } [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; // remove wait view here statusLabel.text = @"Purchase Error!";} break; default: break; } } } 

不太确定是否必须添加或不添加:

 -(void)requestDidFinish:(SKRequest *)request { } -(void)request:(SKRequest *)request didFailWithError:(NSError *)error { NSLog(@"Failed to connect with error: %@", [error localizedDescription]); } 

这是有史以来最简单的代码。 不知道苹果是否会批准,但它工作。 这适用于iOS 4.3及更高版本,我认为它很棒,但是并没有实现收据,因此一些聪明的孩子可以免费获得硬币。

不要忘了在iTunes Connect上创build消耗品,并使用您在此创build的正确ID更改ID“com.IAPID.10coins”。

“paymentWithProductIdentifier”被弃用,但仍然有效,修复它改变了“paymentWithProduct”,并find一种方法来添加IAP ID。 我尝试过,但没有成功。

这是ARC准备,除了“SFHFKeychainUtils.m”,您可以尝试修复它或禁用单个文件上的ARC,这里是教程: http : //www.leesilver.net/1/post/2011/8/禁止弧上的某些-文件正在xcode.html

您还必须将ScoreKit和Security框架添加到您的项目中。

对于消费itens,这就是它! 对于非消耗品,您必须添加一个RESTOREbutton,否则苹果公司会给您一个拒绝。 但是这很简单:

 // RESTORE - (IBAction)IAPRestore:(id)sender { [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; } - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue { NSLog(@"Restore completed transactions finished."); NSLog(@" Number of transactions in queue: %d", [[queue transactions] count]); for (SKPaymentTransaction *trans in [queue transactions]) { NSLog(@" transaction id %@ for product %@.", [trans transactionIdentifier], [[trans payment] productIdentifier]); NSLog(@" original transaction id: %@ for product %@.", [[trans originalTransaction] transactionIdentifier], [[[trans originalTransaction] payment]productIdentifier]); if ([[[trans payment] productIdentifier] isEqual: @"com.AppID.IAPID"]) { NSLog(@"Purchase Restored"); // Do your stuff to unlock } } UIAlertView *tmp = [[UIAlertView alloc] initWithTitle:@"Purchases Restored" message:@"Your previously purchased products have been restored!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; [tmp show]; } 

我希望这对某个人有用,苹果认可它:)

更新:苹果批准它,销售情况良好,iOS 4.3,5和6销售正在工作:)更新2:testing和工作完美的Xcode 4.6和iOS 6.1.2。