为什么不';t用户在Swift iOS中获得应用内购买确认?
我将在警报视图中显示IAP选项,下面是我用于此操作的代码:为什么不';t用户在Swift iOS中获得应用内购买确认?,ios,swift,in-app-purchase,Ios,Swift,In App Purchase,我将在警报视图中显示IAP选项,下面是我用于此操作的代码: paidAlert.addAction(UIAlertAction(title: "Purchase", style: UIAlertAction.Style.default, handler: { (action) in IAPHandler.shared.purchaseMyProduct(index: 0) })) paidAlert.addActi
paidAlert.addAction(UIAlertAction(title: "Purchase", style: UIAlertAction.Style.default, handler: { (action) in
IAPHandler.shared.purchaseMyProduct(index: 0)
}))
paidAlert.addAction(UIAlertAction(title: "Restore", style: UIAlertAction.Style.default, handler: { (action) in
IAPHandler.shared.restorePurchase()
}))
paidAlert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: { (action) in
}))
我在另一个Swift文件中处理实际IAP,该文件发布在此处:
import UIKit
import StoreKit
enum IAPHandlerAlertType{
case disabled
case restored
case purchased
func message() -> String{
switch self {
case .disabled:
let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.notificationOccurred(.error)
return "Purchases are disabled on your device."
case .restored:
let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.notificationOccurred(.success)
return "Unlimited strategies have been successfully unlocked. You can restore this purchase using this Apple ID on other devices."
case .purchased:
let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.notificationOccurred(.success)
return "Unlimited strategies have been successfully unlocked. You can restore this purchase using this Apple ID on other devices."
}
}
}
class IAPHandler: NSObject {
static let shared = IAPHandler()
let NON_CONSUMABLE_PURCHASE_PRODUCT_ID = "com.isaranjha.opc.fullversion"
fileprivate var productID = ""
fileprivate var productsRequest = SKProductsRequest()
fileprivate var iapProducts = [SKProduct]()
var purchaseStatusBlock: ((IAPHandlerAlertType) -> Void)?
// MARK: - MAKE PURCHASE OF A PRODUCT
func canMakePurchases() -> Bool { return SKPaymentQueue.canMakePayments() }
func purchaseMyProduct(index: Int){
if iapProducts.count == 0 { return }
if self.canMakePurchases() {
let product = iapProducts[index]
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
productID = product.productIdentifier
} else {
purchaseStatusBlock?(.disabled)
}
}
// MARK: - RESTORE PURCHASE
func restorePurchase(){
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
// MARK: - FETCH AVAILABLE IAP PRODUCTS
func fetchAvailableProducts(){
// Put here your IAP Products ID's
let productIdentifiers = NSSet(objects: NON_CONSUMABLE_PURCHASE_PRODUCT_ID
)
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
productsRequest.delegate = self
productsRequest.start()
}
}
extension IAPHandler: SKProductsRequestDelegate, SKPaymentTransactionObserver{
// MARK: - REQUEST IAP PRODUCTS
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
iapProducts = response.products
for product in iapProducts{
let numberFormatter = NumberFormatter()
numberFormatter.formatterBehavior = .behavior10_4
numberFormatter.numberStyle = .currency
numberFormatter.locale = product.priceLocale
let price1Str = numberFormatter.string(from: product.price)
print(product.localizedDescription + "\nfor just \(price1Str!)")
}
}
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
purchaseStatusBlock?(.restored)
}
// MARK:- IAP PAYMENT QUEUE
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
print("purchased")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
purchaseStatusBlock?(.purchased)
break
case .failed:
print("failed")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
case .restored:
print("restored")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
break
default: break
}}}
}
}
导入UIKit
进口存储套件
枚举IapHandlereType{
案例残疾
案件恢复
购买的箱子
func message()->字符串{
切换自身{
案例.残疾人:
让notificationFeedbackGenerator=UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.NotificationOccurrent(.error)
return“设备上已禁用购买。”
案件.恢复:
让notificationFeedbackGenerator=UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.NotificationOccursed(.success)
return“无限策略已成功解锁。您可以在其他设备上使用此Apple ID还原此购买。”
案例。购买:
让notificationFeedbackGenerator=UINotificationFeedbackGenerator()
notificationFeedbackGenerator.prepare()
notificationFeedbackGenerator.NotificationOccursed(.success)
return“无限策略已成功解锁。您可以在其他设备上使用此Apple ID还原此购买。”
}
}
}
类IAPHandler:NSObject{
静态let shared=IAPHandler()
让非消耗品购买产品\u ID=“com.isaranjha.opc.fullversion”
fileprivate var productID=“”
fileprivate var productsRequest=SKProductsRequest()
fileprivate var iapProducts=[SKProduct]()
var purchaseStatusBlock:((IAPHandlerAlertType)->无效)?
//马克:-购买产品
func canMakePurchases()->Bool{return SKPaymentQueue.canMakePayments()}
func purchaseMyProduct(索引:Int){
如果iapProducts.count==0{return}
如果self.canMakePurchases(){
let product=iapProducts[index]
let payment=SKPayment(产品:产品)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(付款)
打印(“要购买的产品:\(PRODUCT.productIdentifier)”)
productID=product.productIdentifier
}否则{
purchaseStatusBlock?(.禁用)
}
}
//MARK:-恢复购买
func restorepourchase(){
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
//MARK:-获取可用的IAP产品
func fetchAvailableProducts(){
//把你的IAP产品ID放在这里
让productIdentifiers=NSSet(对象:非消耗品\采购\产品\ ID
)
productsRequest=SKProductsRequest(productIdentifiers:productIdentifiers as!Set)
productsRequest.delegate=self
productsRequest.start()
}
}
扩展IAPHandler:SKProductsRequestDelegate,SKPaymentTransactionObserver{
//马克:-申请IAP产品
func productsRequest(uRequest:SKProductsRequest,didReceive response:SKProductsResponse){
如果(response.products.count>0){
iapProducts=response.products
对于iapProducts中的产品{
设numberFormatter=numberFormatter()
numberFormatter.formatterBehavior=.behavior10\u 4
numberFormatter.numberStyle=.currency
numberFormatter.locale=product.priceLocale
让price1Str=numberFormatter.string(from:product.price)
打印(product.localizedDescription+“\n仅适用于\(price1Str!)”)
}
}
}
func paymentQueueRestoreCompletedTransactionsFinished(队列:SKPaymentQueue){
purchaseStatusBlock?(.已还原)
}
//标记:-IAP付款队列
func paymentQueue(queue:SKPaymentQueue,updatedTransactions事务:[SKPaymentTransaction]){
对于事务:事务中的任何对象{
如果let trans=交易作为?SKPaymentTransaction{
开关trans.transactionState{
案例。购买:
印刷品(“购买”)
SKPaymentQueue.default().finishTransaction(事务为!SKPaymentTransaction)
purchaseStatusBlock?(.已购买)
打破
案例。失败:
打印(“失败”)
SKPaymentQueue.default().finishTransaction(事务为!SKPaymentTransaction)
打破
案件.恢复:
打印(“恢复”)
SKPaymentQueue.default().finishTransaction(事务为!SKPaymentTransaction)
打破
默认值:中断
}}}
}
}
但是,多个用户(但不是所有用户)报告说他们可以购买IAP罚款(它向他们和所有人收取费用),但他们没有得到任何确认,即我已编码(警告说购买成功等),因此没有购买的功能。我们能找到的唯一解决办法是,用户需要停止应用程序的多任务处理,再次进入初始IAP购买警报,但选择恢复,然后它会相应地提示,并且功能被解锁
我不知道我在这方面哪里出了问题,但鉴于恢复功能似乎是如何工作的,我假设我在实际购买中遗漏了一些东西,这些东西将被称为案例。正确购买并显示警报
非常感谢您的帮助。您的
.purchased
状态出现逻辑错误-在更新解锁或处理购买所需的任何状态之前,您不应完成交易。在调用可选的purchaseStatusBlock