SKPaymentTransactionStatePurchased 多次调用错误
Posted
技术标签:
【中文标题】SKPaymentTransactionStatePurchased 多次调用错误【英文标题】:SKPaymentTransactionStatePurchased called multiple times by error 【发布时间】:2013-11-21 13:13:25 【问题描述】:我正在进行应用内购买,但我有一个错误,我找不到它的来源...
首先,我有一个按钮,当您单击它时,我的应用程序会请求产品,捕获响应,您付款并获得产品(一切正常)。 但是我的问题来了。如果我点击按钮再次购买任何东西,我会收到两次提醒我买了两次东西。即使我第三次点击,我也会收到 3 次提醒我买了东西 3 次,根据我点击的次数分别是 4 次和 5 次。
所以似乎有些变量一直在存储请求。这是我的代码:
这会验证产品 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;
非常感谢您的宝贵时间!
【问题讨论】:
【参考方案1】:我的问题是每次单击按钮或更改视图时都会复制观察者。
解决方案是添加一个标志,看看是否已经添加了观察者。
static bool hasAddObserver=NO;
PAYMENT METHOD
if (!hasAddObserver)
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
hasAddObserver=YES;
.....
【讨论】:
根据 Apple 的文档,“您的应用程序应在应用程序初始化期间将观察者添加到支付队列。” 所以您的解决方案有效,但更好的是开始观察交易一次只要您的应用启动。【参考方案2】:我遇到了同样的问题,我会在 IAP 上点击购买,然后会收到来自 Apple 的多次回复和购买。
每次我离开时都会调用addTransactionObserver()
,然后通过viewDidLoad()
返回视图。
我需要在viewWillDisappear()
中取消观察它:
override func viewWillDisappear()
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
我无法使用标志来阻止像 mursang 回答中的多个观察者,因为我在其他视图中侦听了事务。
【讨论】:
好吧,我的观察者是 UIViewController 的后代,因为我需要它在 updatedTransactions: 方法中执行一些 UI 操作。在调用 viewDidLoad 方法并创建该 UIViewController 的实例之前,这是不可能完成的。【参考方案3】:你还记得打电话吗
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
什么时候购买完成?
【讨论】:
它是在“case SKPaymentTransactionStatePurchased:”中添加的,我需要在其他地方添加它吗?【参考方案4】:Swift 3:根据@sponrad 的回答
override func viewWillDisappear(_ animated: Bool)
SKPaymentQueue.default().remove(self)
【讨论】:
有谁知道为什么需要这个?!你会认为我们不需要这个,它会包含在代码的事务完成部分中。【参考方案5】:[addTransactionObserver]
应该只运行一次。
所以你可以使用单例模式来解决这个问题。
+ (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;
【讨论】:
但是不能解决这个问题。您最好在 didFinishLaunchingWithOptions 中调用它,例如 [InAppPurchase sharedInstance];当你想买东西时,你可以像 [[InAppPurchase sharedInstance] buyProduct:(SKProduct) myProduct];以上是关于SKPaymentTransactionStatePurchased 多次调用错误的主要内容,如果未能解决你的问题,请参考以下文章