【发布时间】:2018-10-06 17:57:21
【问题描述】:
您好,我正在 App Store 上发布我的应用,因为他们一直坚持我的应用内购买设置不正确。
在沙盒中亲自测试后,一切正常。
这是他们发给我的消息,我在下面粘贴了我的代码。
感谢您抽出宝贵时间帮助我!
指南 2.1 - 性能 - 应用完整性
我们发现您的应用内购买产品存在一个或多个错误 在通过 Wi-Fi 运行 iOS 12 的 iPhone 和 iPad 上进行审核时。
具体来说,您的应用内购买按钮不起作用。
后续步骤
在您的服务器上验证收据时,您的服务器需要能够 处理从 Apple 获取收据的生产签名应用程序 测试环境。推荐的方法适用于您的生产 服务器始终根据生产 App Store 验证收据 第一的。如果验证失败并显示错误代码“使用沙盒收据 在生产中,”您应该针对测试环境进行验证 而是。
class IAPService: NSObject {
private override init() {}
static let shared = IAPService()
var products = [SKProduct]()
let paymentQueue = SKPaymentQueue.default()
func getProducts() {
let products: Set = [IAPProduct.consumable.rawValue,
IAPProduct.nonConsumable.rawValue]
let request = SKProductsRequest(productIdentifiers: products)
request.delegate = self
request.start()
paymentQueue.add(self)
}
func purchase(product: IAPProduct) {
for p in products {
if p.productIdentifier == product.rawValue {
let payment = SKPayment(product: p)
paymentQueue.add(payment)
print("Adding product to payment queue")
}
}
}
func restorePurchase() {
print("Restoring purchases")
paymentQueue.restoreCompletedTransactions()
}
func givePurchasedProduct(productID: String) {
if productID.range(of: "Zap") != nil {
NotificationCenter.default.post(name: Notification.Name.init("zapPurchased"), object: nil)
} else if productID.range(of: "Ads") != nil {
NotificationCenter.default.post(name: Notification.Name.init("noAdsPurchased"), object: nil)
}
}
}
extension IAPService: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
self.products = response.products
for product in response.products {
print(product.localizedTitle)
}
}
}
extension IAPService: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
print(transaction.transactionState.status(), transaction.payment.productIdentifier)
switch transaction.transactionState {
case .purchasing, .deferred: break // do nothing
case .purchased:
queue.finishTransaction(transaction)
givePurchasedProduct(productID: transaction.payment.productIdentifier)
case .restored:
self.restorePurchase()
queue.finishTransaction(transaction)
case .failed:
queue.finishTransaction(transaction)
}
}
}
}
extension SKPaymentTransactionState {
func status() -> String {
switch self {
case .deferred:
return "deferred"
case .failed:
return "failed"
case .purchased:
return "purchased"
case .purchasing:
return "purchasing"
case .restored:
return "restored"
}
}
}
【问题讨论】:
-
“您的应用内购买按钮不起作用” 那么响应按钮的代码在哪里?他们告诉过你,这就是问题所在。 — 另外,单例如何充当 SKPaymentTransactionObserver?你需要展示更多的架构来证明这是可能的。
-
您的事务观察器中的逻辑也不正确;在您成功坚持购买之前,您正在致电
finishTransaction。在确认您的应用已识别购买之前,您不得完成交易。由于您只是触发通知,因此您无法确定是否发生了这种情况。此外,您恢复完成的事务将创建一个无限循环。在您的事务观察器中,restored状态应与.purchased状态相同。 -
@matt 为什么事务观察者不能是单例(除了不使用单例的一般原因)?事务观察者实际上需要与应用程序本身相同的生命周期。如果我不使用单例,我将对象实例设为应用委托的属性,效果类似
-
@Paulw11 我毫不怀疑 you 早早地创建了这个单例并将其分配给一个持久变量/属性并将其设置为观察者。我没有理由认为 OP 也在做同样的事情。我要求OP向我展示证据,仅此而已。代码不起作用,我为什么要把任何事情视为理所当然?
-
好的,我同意。我们需要知道如何以及何时实例化它们的对象。在阅读您的评论时,我认为您是在一般情况下向 Singleton 观察者提出问题,而不是围绕此代码的实例化的细节。
标签: ios swift in-app-purchase