2

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

所以基本上这就是它在表格视图上的工作方式。首先识别产品:

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

所以我正在尝试制作一个简单的按钮来触发操作,如下所示:

 - (IBAction)button10Coins:(id)sender {

     SKPayment * payment = [SKPayment paymentWithProduct:@"com.companyname.10coins"];
     [[SKPaymentQueue defaultQueue] addPayment:payment];
 }

但我收到警告“不兼容的指针类型”。

在它启动后,代码运行良好,我能够完成购买,唯一的问题是正确创建 IBAction。有任何想法吗?

谢谢!!!

4

3 回答 3

3

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

定义 kStoredData @“应用内购买对象”(这是用于对象声明)

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

请通知它是否适合您.. :)

于 2013-01-05T04:36:59.800 回答
2

paymentWithProduct:需要一个SKProduct *参数,而您正在传递一个NSString. 您需要将您的产品从您的_products阵列中取出并通过它。

于 2013-01-05T04:04:27.243 回答
2

感谢所有在这里帮助过我的人!我终于让它工作了。

我出来了一个不同的代码。我将尝试解释我在这里所做的一切,所以如果有人想做同样的事情。

首先在 iOS Provisioning Portal 上创建 App ID,并在 iTunes Connect 上创建 IAP 购买。

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

现在代码:

。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"

按钮:

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

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

不要忘记在 iTunes Connect 上创建 Consumable 项目,并使用您在那里创建的正确 ID 更改 ID“com.IAPID.10coins”。

“paymentWithProductIdentifier”已被弃用但仍然有效,要修复它,将其更改为“paymentWithProduct”并找到添加 IAP ID 的方法。我试过但没有成功。

这是 ARC 就绪,除了“SFHFKeychainUtils.m”,您可以尝试修复它或在该单个文件上禁用 ARC,这里是教程: http: //www.leesilver.net/1/post/2011/8/禁用-arc-on-certain-files-in-xcode.html

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

对于消耗品,就是这样!对于非消耗品,您必须添加一个 RESTORE 按钮,否则 Apple 会拒绝您。但这很容易:

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

 }

我希望这对某人有用并且Apple批准它:)

更新:Apple 批准了它,销售情况良好,iOS 4.3、5 和 6 销售正常 :) 更新 2:在 Xcode 4.6 和 iOS 6.1.2 上测试和工作完美。

于 2013-01-05T19:38:50.820 回答