Bonjour, j'ai du mal à faire publier mon application sur l'App Store car ils insistent sur le fait que mes achats in-app ne sont pas configurés correctement.
En les testant moi-même dans le bac à sable, tout a fonctionné correctement.
Voici le message qu'ils m'ont envoyé, j'ai collé mon code ci-dessous.
Merci de prendre le temps de m'aider !
Ligne directrice 2.1 - Performance - Complétude de l'application
Nous avons constaté que vos produits d'achat in-app présentaient un ou plusieurs bogues lorsqu'ils ont été examinés sur un iPhone et un iPad fonctionnant sous iOS 12 en Wi-Fi.
Plus précisément, vos boutons d'achat dans l'application ne fonctionnent pas.
Les prochaines étapes
Lorsque vous validez des reçus sur votre serveur, celui-ci doit pouvoir de gérer une application signée en production qui reçoit ses reçus de l'environnement de environnement de test d'Apple. L'approche recommandée est que votre serveur de production de production valide toujours les reçus par rapport à l'App Store de production de production. Si la validation échoue avec le code d'erreur "Sandbox receipt used dans la production", vous devez valider contre l'environnement de test à la place.
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"
}
}
}