我正在关注this RW 教程,和很多 IAP 和 Storekit 教程一样,他们讨论了用户第一次购买 IAP 的流程,但没有详细说明当用户购买 IAP 时应用程序如何运行。已购买 IAP 的用户再次打开应用程序。
当我发现问题的关键时更新我的问题:
据我所知,阻止/显示内容的代码是对 (1) 收据和 (2) SessionID
的查找……他没有详细介绍教程 SessionID 的用途或者它是否仅作为教程演示的一部分。例如,它仅在调用 uploadReceipt
时设置(仅在调用 handlePurchasedState
或 handleRestoredState
时调用)。换句话说,如果用户打开已经订阅的应用,则不会运行任何代码来设置 SessionID
,因此内容永远不会解锁?
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SKPaymentQueue.default().add(self)
SubscriptionService.shared.loadSubscriptionOptions()
return true
}
}
// MARK: - SKPaymentTransactionObserver
extension AppDelegate: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue,
updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchasing:
handlePurchasingState(for: transaction, in: queue)
case .purchased:
handlePurchasedState(for: transaction, in: queue)
case .restored:
handleRestoredState(for: transaction, in: queue)
case .failed:
handleFailedState(for: transaction, in: queue)
case .deferred:
handleDeferredState(for: transaction, in: queue)
}
}
}
func handlePurchasingState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("User is attempting to purchase product id: \(transaction.payment.productIdentifier)")
}
func handlePurchasedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("User purchased product id: \(transaction.payment.productIdentifier)")
queue.finishTransaction(transaction)
SubscriptionService.shared.uploadReceipt { (success) in
DispatchQueue.main.async {
NotificationCenter.default.post(name: SubscriptionService.purchaseSuccessfulNotification, object: nil)
}
}
}
func handleRestoredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("Purchase restored for product id: \(transaction.payment.productIdentifier)")
queue.finishTransaction(transaction)
SubscriptionService.shared.uploadReceipt { (success) in
DispatchQueue.main.async {
NotificationCenter.default.post(name: SubscriptionService.restoreSuccessfulNotification, object: nil)
}
}
}
func handleFailedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("Purchase failed for product id: \(transaction.payment.productIdentifier)")
}
func handleDeferredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) {
print("Purchase deferred for product id: \(transaction.payment.productIdentifier)")
}
}
最佳答案
每次用户启动应用程序时,您都不会收到购买通知,但从技术上讲,您可以在每次程序运行时验证应用程序收据并重新处理每个 IAP。这看起来效率很低。您的应用程序应该只在购买时跟踪已购买的商品。
如果应用被删除并重新安装,或者用户将其安装在其他设备上,您应该提供“恢复应用内购买”功能来刷新应用收据并验证它。
关于ios - Storekit 和处理已购买 IAP 的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47763691/