Swift 应用内购买

3

希望这些信息足以帮助我解决问题。

我正在使用一个模板源代码设置应用内购买。在我的MKStoreManager.m文件中,我设置了应用内购买的featureID(例如:static NSString *featureAId = @"com.logannat.myfirstgameTier1";

在游戏中单击实际按钮时,会调用一个方法。

- (void) buyFeature:(SKProduct*) product
{
    if ([SKPaymentQueue canMakePayments])
    {
        SKPayment *payment = [SKPayment paymentWithProduct:product];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
}

最终被调用了。我设置了断点,并发现错误出在该代码的最后一行。

出现在断点状态中的变量有:

  1. self = (MKStoreManager *)"参考号"
  2. product = (SKProduct *) 空值 以及
  3. payment = (SKPayment *) "参考号"

我似乎无法弄清楚问题出在哪里。任何帮助都将不胜感激,谢谢。


1
什么错误?更重要的是,找出为什么productnil - rmaddy
1个回答

0
我现在没有 Swift,所以我会给你 Xcode 代码,请相应地转换语法,这并不难。 所以这是应用内购买的完整生命周期。 在您的头文件中调用这些委托并设置布尔值以检查您购买的状态。
#import <UIKit/UIKit.h> 
BOOL arefavorite_access;
BOOL areAdsRemoved;
@interface ViewController : UIViewController<SKProductsRequestDelegate, SKPaymentTransactionObserver>{
}

- (IBAction)purchase;
- (IBAction)restore;
- (IBAction)tapsRemoveAds:(id)sender;
@end

你需要在按钮选择器的touchupinside事件上绑定这个tapsRemoveAds方法,它就可以开始工作了。

- (IBAction)tapsRemoveAds:(id)sender{
    UIButton*btn=(UIButton*)sender;
    NSString *featureAId = @"com.logannat.myfirstgameTier1";

    NSLog(@"User requests to remove ads");
    if([SKPaymentQueue canMakePayments]){
        NSLog(@"User can make payments");
        SKProductsRequest *productsRequest;
        if (btn.tag==1) {            
            productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject: featureAId]];
            _protype= featureAId;
        }

        productsRequest.delegate = self;
        [productsRequest start];

        }
        else{
            NSLog(@"User cannot make payments due to parental controls");
            //this is called the user cannot make payments, most likely due to parental controls
        }

}

产品请求方法

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    SKProduct *validProduct = nil;
    int count = [response.products count];
    if(count > 0){
        validProduct = [response.products objectAtIndex:0];
        NSLog(@"Products Available!");
        [self purchase:validProduct];
    }
    else if(!validProduct){
        NSLog(@"No products available");
        //this is called if your product id is not valid, this shouldn't be called unless that happens.
    }
}

- (IBAction)purchase:(SKProduct *)product{
    SKPayment *payment = [SKPayment paymentWithProduct:product];

    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (IBAction) restore{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
    NSLog(@"%@",queue );
    NSLog(@"Restored Transactions are once again in Queue for purchasing %@",[queue transactions]);

    NSMutableArray *purchasedItemIDs = [[NSMutableArray alloc] init];
    NSLog(@"received restored transactions: %i", queue.transactions.count);

    for (SKPaymentTransaction *transaction in queue.transactions) {
        NSString *productID = transaction.payment.productIdentifier;
        [purchasedItemIDs addObject:productID];
        NSLog (@"product id is %@" , productID);
        _protype=productID;
        [self doRemoveAds];

        // here put an if/then statement to write files based on previously purchased items
        // example if ([productID isEqualToString: @"youruniqueproductidentifier]){write files} else { nslog sorry}
    }
    if(queue.transactions.count==0){

        [Utilities showOKAlertWithTitle:@"Restore purchase" message:@"you have no product available for restoration"];

    }

}


- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
    for(SKPaymentTransaction *transaction in transactions){
        switch(transaction.transactionState){
            case SKPaymentTransactionStatePurchasing: NSLog(@"Transaction state -> Purchasing");
                //called when the user is in the process of purchasing, do not add any of your own code here.
                break;
            case SKPaymentTransactionStatePurchased:
                //this is called when the user has successfully purchased the package (Cha-Ching!)
                [self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                NSLog(@"Transaction state -> Purchased");
                [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"Transaction state -> Restored");

                _protype=transaction.payment.productIdentifier;
                [self doRemoveAds];
                //add the same code as you did from SKPaymentTransactionStatePurchased here
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
                break;
            case SKPaymentTransactionStateFailed:
                //called when the transaction does not finish
                if(transaction.error.code == SKErrorPaymentCancelled){

                    NSLog(@"Transaction state -> Cancelled");
                    //the user cancelled the payment ;(

                }
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
                break;
        }
    }
}


- (void)doRemoveAds{
    //   // [self.bannerView setAlpha:0];

     NSString *featureAId = @"com.logannat.myfirstgameTier1";
 NSString *featureAIdnumber2 = @"com.logannat.myfirstgameTier2";
    if([_protype isEqualToString:featureAId]){

        arefavorite_access = YES;
        [[NSUserDefaults standardUserDefaults] setBool:arefavorite_access forKey:frareFavoriteRemoved];
        [[NSUserDefaults standardUserDefaults] synchronize];

    }

    else if([_protype isEqualToString: featureAIdnumber2]){

        areAdsRemoved = YES;
        [[NSUserDefaults standardUserDefaults] setBool:areAdsRemoved forKey:frareAdsRemoved];
        [[NSUserDefaults standardUserDefaults] synchronize];

    }

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
   // [self showpopUp:self];

}

如果这个答案对您有帮助,请投票并接受答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接