2015-03-24 71 views
4

我一直在尝试在iOS上测试一些易损件IAP,并且出现一个奇怪的错误。弹出一个警告:“这个应用程序内购买已经被购买,它将被免费恢复。[环境:沙盒]”。沙箱试图恢复易损件IAP

我检查过了,我确定我的IAP在iTunesConnect中可以使用。看来我的验证过程在某种程度上失败了,但我不希望这个错误信息。有人对这个有经验么?

+0

好像我有一个类似的问题。你修好了吗? – Vladius 2015-04-01 18:14:17

+0

我也面临同样的问题。你有没有找到解决方案? – 2017-07-11 14:06:12

回答

7

我不知道这是否是正确的行动,但呼吁:

[[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 
上的重复交易

清除出来。我怀疑,由于停止在调试器或其他东西,我从来没有在成功案例中调用它。

4

也许您解决您的问题了,但我遇到了同样的问题,有一些额外的解决方案要点:

对不起,我用斯威夫特,但我认为这是可以理解的在这里。

首先,有在你的代码中,两个重要的时刻,你必须包括:

class InAppPurchaseViewController: UIViewController , SKProductsRequestDelegate 
, SKPaymentTransactionObserver //NOTE THIS! 
{ 
override func viewDidLoad() { 
    super.viewDidLoad() 
    // 
    ... 
    ... 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
    // here you create the observer 
} 

//before you leave this ViewController you should delete this Observer. 
//I had a bug which worked like this: when user leaved the IAPViewController without 
//buying something and then came back, viewDidLoad added one more Observer 
// so App crashed on the attempt to buy 
// for example: 

@IBAction func exitTapped(sender: AnyObject) {  
    dismissViewControllerAnimated(true) {() -> Void in 
     SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
    } 
} 

您添加的观测后,别忘了完成交易:

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
    for transaction in transactions { 
     switch transaction.transactionState { 
     case .Restored: 
      print("Restored") 
      break 
     case .Failed: 
      print("Failed") 
     //FINISH TRANSACTION 
      SKPaymentQueue.defaultQueue().finishTransaction(transaction) 
      break 
     case .Purchasing: 
      print("Purchasing") 
      break 
     case .Purchased: 
     // DO your stuff here 
     // ... 
     // and FINISH TRANSACTION 
      SKPaymentQueue.defaultQueue().finishTransaction(transaction) 
      } 
      break 
     case .Deferred: 
      print("Deferred") 
      break 
     } 
    } 
} 

我在这里解决的另一个问题是:我忘了添加完成代码交易行,所以我已经与易损耗IAP打开了交易。

当我试图再次购买这个沙盒用户时,我收到了消息“这个应用程序内购买已经被购买了,它将被免费恢复[环境:沙盒]”这再次发生了甚至在我添加FinishTransaction之后。我改变了沙箱用户。每次运行App时,App都会提示FirstSandBoxUser iTunes密码。灾难......很烦人......

每次我试图使这一收购与FirstSandBoxUser的transaction.transactionState是.Purchasing,并你不能在这种状态下完成交易!

我做一个假设,如果交易没有完成,StoreKit需要它像一个非消耗品,所以我应该开始一个恢复过程,再搭上一个瞬间完成交易。这是代码:

func paymentQueue // see above 
//.... 
case .Purchasing: 
    print("Purchasing") 
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 
    break 
//... 
} 

func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { 
    for transaction in queue.transactions { 
     queue.finishTransaction(transaction) 
    } 
} 

这足以一次运行这段代码,我认为,这将赶上所有的“采购”交易,恢复他们,完成后。

当然,修复问题后,请删除此附加代码。

祝你好运!

0

当客户端使用的事务未完成时会发生这种情况。

[[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 

你应该在你的应用程序启动阶段注册transactionObserver,保证你会得到通知所有未完成的交易。您应该完成这些交易,并执行其他任何所需的操作,以便将购买的产品正确地交付给用户。

From apples programming guide(重点煤矿):

当你的应用启动,如图清单5-1注册一个事务队列观察。确保观察者随时可以处理事务,而不仅仅是在将事务添加到队列中之后。例如,考虑一下用户在进入隧道之前在您的应用中购买了一些东西的情况。由于没有网络连接,您的应用无法传送购买的内容。 当您的应用下次启动时,StoreKit会再次调用您的事务队列观察器,并在此时传送已购买的内容。同样,如果您的应用无法将交易标记为已完成,则每当您的应用启动时,StoreKit都会调用观察者,直到交易正确完成

他们建议将以下代码注册观察者:

- (BOOL)application:(UIApplication *)application 
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    /* ... */ 

    [[SKPaymentQueue defaultQueue] addTransactionObserver:observer]; 
}