1. 程式人生 > >ios內購(iap)關於問題“您已經購買了此程式內購買(In App Purchase)專案,但尚未下載"的解決方案

ios內購(iap)關於問題“您已經購買了此程式內購買(In App Purchase)專案,但尚未下載"的解決方案

近日在專案內購中遇到“您已經購買了此程式內購買(In App Purchase)專案,但尚未下載”的問題,查閱google和百度各種文章,沒找到合適的解決方案,折騰一整天,終於解決,解決方案貼出來,供大家參考。也是為了驗證這個方案的正確性。歡迎拍磚!

首先說說出現這個問題的原因,一般是購買成功後業務邏輯出了問題(或者是邏輯依賴網路,網路出了問題),沒有成功呼叫finishTransaction,看如下程式碼:

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
	for(SKPaymentTransaction *transaction in transactions) {
		switch (transaction.transactionState) {
				
			case SKPaymentTransactionStatePurchasing:
				// Item is still in the process of being purchased
				break;
				
			case SKPaymentTransactionStatePurchased:
				// Item was successfully purchased!
				[self completeTransaction:transaction];//這兒出了問題拋異常,導致下面一句程式碼沒執行
				
				[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
				break;
				
			case SKPaymentTransactionStateRestored:
				// Return transaction data. App should provide user with purchased product.
                [self restoreTransaction:transaction];
                
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
				
			case SKPaymentTransactionStateFailed:
				// Purchase was either cancelled by user or an error occurred.
				[self failedTransaction:transaction];
                
				// Finished transactions should be removed from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
		}
	}
}

所以每次再次購買的時候就回提示“”您已經購買了此程式內購買(In App Purchase)專案,但尚未下載”。既然問題已經找到,那麼我們就來解決問題吧,問題的關鍵就是把上次未成功處理的transaction處理完,那麼怎麼獲得上次未處理完的transaction呢,可以通過[[SKPaymentQueue defaultQueue] transactions]獲取,我自己是在使用者再次購買行為的時候去做的,當用戶再次購買的時候,先檢查是否有之前未完成的交易,關鍵程式碼如下:

NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
if (transactions.count > 0) {
	//檢測是否有未完成的交易
	SKPaymentTransaction* transaction = [transactions firstObject];
	if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
		[self completeTransaction:transaction];
		[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                return;
	}
}

ok,搞定!