iOS StoreKit – 何时调用 – (void)restoreCompletedTransactions?
我的应用程序内有大量的1次购买IAP。 用户可以购买他们就好了。
我的问题是,我正在与Flurry进行整合,以跟踪实际购买,而不仅仅是购买的恢复,但是我的SKPaymentTransaction
的transactionState
总是作为SKPaymentTransactionStatePurchased
返回,而不是SKPaymentTransactionStateRestored
。
显然SKPaymentTransactionStateRestored
仅在- (void)restoreCompletedTransactions
时调用,但是何时调用此方法?
我的思考过程是购买应该是这样的:1)用户select产品,2)询问用户是否想购买X数量的产品。 3)服务器检查用户之前是否购买过,以及是否通过设置SKPaymentTransactionStateRestored
恢复它。 否则,处理事务并设置SKPaymentTransactionStatePurchased
。 显然这是错误的,我想调用- (void)restoreCompletedTransactions
之间的某处?
谢谢,
将
编辑:
本来我已经发布了一个很长的,不需要的方法来得到我需要做的,但是正如你将在下面看到的,Matt帮我弄清了我正在寻找的variables。
例如,让我们想象一个用户先前购买了我的应用程序,购买了所有可用的非易损件IAP,然后删除了该应用程序。 当用户重新安装应用程序时,我希望能够确定他们何时再次“购买”产品,是原始(第一次)购买还是恢复购买?
我已经实现了“恢复所有购买”button,但是让我们说用户忽略/没有看到它,并试图select他们之前购买的产品。
与正常购买一样,我做了以下事情:
if ([SKPaymentQueue canMakePayments]) { self.productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productID]]; self.productRequest.delegate = self; [self.productRequest start]; } else { //error message here }
用户loginiTunes帐户后,应用程序会让他们知道他们已经购买了这个,现在将会恢复。 下面的委托方法将被调用:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: { [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; if(transaction.originalTransaction) { NSLog(@"Just restoring the transaction"); } else { NSLog(@"First time transaction"); } break; } default: break; } } }
无论交易是恢复还是首次购买, transaction.transactionState
将等于SKPaymentTransactionStatePurchased
。
现在从这个angular度来看,我们如何确定购买是原始还是恢复购买?
简单:如上所见,只要看看transaction.originalTransaction
是否被初始化。 每苹果的说明:/ / 只有当状态是SKPaymentTransactionStateRestored有效。
如果SKPaymentTransaction
的originalTransaction
被初始化,那意味着有一个以前的事务。 否则,这个交易是一个原始的!
再一次,感谢Matt指出我正确的方向,并使逻辑更清洁!
规范期望似乎是您提供了一个调用restoreCompletedTransactions
的还原button。 至于如果用户忽略这一点,只是试图通过你的购买界面,以恢复他已经购买的function,会发生什么,你可能会不必要地担心自己; 文档说:
如果用户试图购买可恢复的产品(而不是使用您实施的恢复界面),则应用程序将接收该项目的常规事务,而不是恢复事务。 但是, 用户不会再为该产品付费。 您的应用程序应将这些交易视为与原始交易的交易完全相同。
商店会提供与用户进行交互的对话框(“您已经购买了这个,是否要再次免费下载?”),免费重新购买的通知将发生在您的paymentQueue:updatedTransactions:
as通常情况下,您可以使用其originalTransaction.transactionIdentifier
来识别原始购买。
如果您正在实施应用程序内购买,则需要在应用程序某处放置恢复button,否则这是拒绝原因。 你可以看看获得的产品列表,inApp购买iPhone的一个发生。
编辑2: 除了放一个button以避免拒绝,可能还有其他的方法。 马特在评论中提出的一个方法是在应用程序启动时恢复,这足以符合苹果的指导原则。
另外看看本教程的最后部分,它提到了同样的问题,并展示了一种简单的实现方法: http : //www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios -6-教程
编辑:
//Draft implementation of transaction observer delegate -(void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction * transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: ... case SKPaymentTransactionStateFailed: ... case SKPaymentTransactionStateRestored: ... default: break; } }; }
Apple IOS SDK文档在这个问题上实际上是误导性的,因为它说:
@property(nonatomic, readonly) SKPaymentTransaction *originalTransaction The contents of this property are undefined except when transactionState is set to SKPaymentTransactionStateRestored.
问题是,当用户点击你的购买button,通过购买过程,最后得到一个消息,他已经支付,他可以免费重新下载,你的观察员不会给你发送一个SKPaymentTransactionStateRestored。 它实际上向您发送一个SKPaymentTransactionStatePurchased。
好消息是,尽pipe有文档,即使您的事务处理状态是SKPaymentTransactionStatePurchased,您也会获得属性originalTransaction。 只要testing看看这个属性是否为零,你就知道这个交易是新购买还是旧购买免费恢复。