Swift IAP订阅处理所有交易



我在swift中的IAP订阅处理中有一个问题。我在我的应用程序中使用IAP订阅,逻辑运行良好,我没有问题。我想检查一下paymentQueue中的交易处理情况。我注意到它正在循环paymentQueue中的所有交易,我必须验证所有交易的收据。这对循环和检查所有事务是必要的吗?还是我应该只关注最后一个事务。最后一笔交易会是最近的交易吗。下面是代码部分的代码片段。

在输出控制台中,我得到以下行(最后三行循环了140次(:总交易计数-140

开始刷新收件人。。。

内部分析Recept。。。。

交易购买

问题:是否有必要处理所有交易(本例中为140(这140是针对同一产品的。无论如何,我都可以避免这种循环,从而改进处理。

提前谢谢。

extension IAPManager: SKPaymentTransactionObserver {

public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {

print(" Total Transaction Count -  (queue.transactions.count)")
for transaction in transactions {
switch (transaction.transactionState) {
case .purchased:
notifyIsPurchased(transaction: transaction)
SKPaymentQueue.default().finishTransaction(transaction)
print ("Transaction Purchased")
break
case .failed:
SKPaymentQueue.default().finishTransaction(transaction)
self.failureBlock?(transaction.error)
cleanUp()
break
case .restored:
notifyIsPurchased(transaction: transaction)
SKPaymentQueue.default().finishTransaction(transaction)
print("restored")
break
case .deferred:
print("defered")
break
case .purchasing:
print("purchasing")
break
default:
break
}
}
}
private func notifyIsPurchased(transaction: SKPaymentTransaction) {
refreshSubscriptionsStatus(callback: {
self.successBlock?()
self.cleanUp()
}) { (error) in
// couldn't verify receipt
self.failureBlock?(error)
self.cleanUp()
}
}
func refreshSubscriptionsStatus(callback : @escaping SuccessBlock, failure : @escaping FailureBlock) {

print("Start refreshing reciept...")
self.refreshSubscriptionSuccessBlock = callback
self.refreshSubscriptionFailureBlock = failure

guard let receiptUrl = Bundle.main.appStoreReceiptURL else {
print("No reciept")
refreshReceipt()
return
}

let urlString = "https://sandbox.itunes.apple.com/verifyReceipt"
//let urlString = "https://buy.itunes.apple.com/verifyReceipt"
let receiptData = try? Data(contentsOf: receiptUrl).base64EncodedString()
let requestData = ["receipt-data" : receiptData ?? "", "password" : self.sharedSecret, "exclude-old-transactions" : true] as [String : Any]
var request = URLRequest(url: URL(string: urlString)!)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
let httpBody = try? JSONSerialization.data(withJSONObject: requestData, options: [])
request.httpBody = httpBody

URLSession.shared.dataTask(with: request)  { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
if let json = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments){
//print (json)
self.parseReceipt(json as! Dictionary<String, Any>)
return
}
} else {
print("error validating receipt: (error?.localizedDescription ?? "")")
}
self.refreshSubscriptionFailureBlock?(error)
self.cleanUpRefeshReceiptBlocks()
}
}.resume()
}
private func parseReceipt(_ json : Dictionary<String, Any>) {

print("Inside Parsing Reciept....")


guard let receipts_array = json["latest_receipt_info"] as? [Dictionary<String, Any>] else {
self.refreshSubscriptionFailureBlock?(nil)
self.cleanUpRefeshReceiptBlocks()
return
}
process the receipt array and check if it is expired or valid...
}

根据苹果公司的文档,不能100%保证[SKPaymentTransaction]中的最后一笔交易是您最近的交易,其中写道transactions属性为:

已更新的事务的数组。

这里没有明确说明transactions是正确排序的,尽管数组通常用于顺序重要的元素。。但是,您可以通过访问transactionDate属性来轻松地自己对事务进行排序。这里有一个例子:

func paymentQueue(_ queue: SKPaymentQueue,
updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
let ascendingTransactions = transactions.filter({$0.transactionDate != nil})
.sorted(by: {$1.transactionDate! > $0.transactionDate!})
let latestTransaction = ascendingTransactions.last

}
}

最新更新