SKPaymentTransactionStatePurchased错误地多次调用

时间:2013-11-21 13:13:26

标签: ios in-app-purchase skproduct

我正在进行应用内购买,但我有一个我无法找到它的错误...

首先,我有一个按钮,当您点击它时,我的应用程序请求产品,捕获响应,您付款,然后您获得产品(一切正常)。 但这是我的问题。如果我再次点击按钮购买任何东西,我会收到两次警告,我买了两次。即使我第三次点击,我也会收到三次警报,我根据我点击的次数购买了三次,四次和五次。

所以看起来有些变量会一直存储请求。这是我的代码:

验证产品ID

- (void) validateProductIdentifiers
{ 
NSString *monedas = @" ID FROM PRODUCT ";
NSSet *product = [NSSet setWithObject:monedas];

productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:product];

productsRequest.delegate = self;
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[productsRequest start];
NSLog(@"STARTED REQUEST");
}

处理Apple的响应

- (void)productsRequest:(SKProductsRequest *)request
 didReceiveResponse:(SKProductsResponse *)response
{


productsRequest=nil;

int found=0;

SKProduct *paraPagar;
skProducts = response.products;

for (SKProduct * skProduct in skProducts) {
             NSLog(@"Found product: %@ %@ %0.2f",
          skProduct.productIdentifier,
          skProduct.localizedTitle,
          skProduct.price.floatValue);
    found=1;

    paraPagar = skProduct;
}
if (found==1){ 
    payment = [SKMutablePayment paymentWithProduct:paraPagar];
    payment.quantity = 1;

    [[SKPaymentQueue defaultQueue]addPayment:payment];

}else{ 

 //error (not relevant code)

}
}

接受付款并完成交易

- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions
{



for (SKPaymentTransaction *transaction in transactions) {
    switch (transaction.transactionState) {

        case SKPaymentTransactionStatePurchased:
            NSLog(@"BOUGHT");

            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            [self completeTransaction:transaction];


            break;
        case SKPaymentTransactionStateFailed:
            NSLog(@"FAILED");
           [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

            [self failedTransaction];
            break;
        case SKPaymentTransactionStateRestored:
            NSLog(@"RESTORED");
            //[self restoreTransaction:transaction];
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        case SKPaymentTransactionStatePurchasing:
            NSLog(@"PURCHASING");
        default:
            break;
    }

}

}

非常感谢你的时间!

5 个答案:

答案 0 :(得分:10)

修复了问题。

问题是,每次点击按钮或更改视图时,观察者都会被复制。

解决方案是添加一个标志,以查看是否已添加观察者。

static bool hasAddObserver=NO;

PAYMENT METHOD{
if (!hasAddObserver) {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    hasAddObserver=YES;
}
.....

答案 1 :(得分:3)

我遇到了同样的问题,我会在IAP上点击购买,并会收到Apple的多个回复和购买。

每次离开时都会调用{p> addTransactionObserver(),并通过viewDidLoad()返回到视图。

我需要在viewWillDisappear()

中取消观察
override func viewWillDisappear() {
  SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}

我无法使用标志来阻止多个观察者,例如在mursang的回答中,因为我在其他视图中听取了交易。

答案 2 :(得分:1)

你还记得打电话吗

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

购买完成后?

答案 3 :(得分:0)

Swift 3 :根据@sponrad回答

override func viewWillDisappear(_ animated: Bool) { 
    SKPaymentQueue.default().remove(self)
}

答案 4 :(得分:-1)

[addTransactionObserver] should  run only once time. 
so you can use singleton pattern to solve this problem.

+ (InAppPurchase *)sharedInstance
{
    static dispatch_once_t once;
    static InAppPurchase * sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] initWithProductIdentifiers:nil];
    });
    return sharedInstance;
}

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {

    if ((self = [super init])) {
        // Add self as transaction observer
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    return self;
}