Вот каково было их сообщение:
Мы обнаружили, что в ваших продуктах, приобретаемых через приложение, обнаружена одна или несколько ошибок, которые ухудшают взаимодействие с пользователем. В частности, кнопка «Удалить рекламу» не работала. Ознакомьтесь с подробной информацией и ресурсами ниже и выполните следующие шаги.
а затем:
Дальнейшие шаги
При проверке квитанций на вашем сервере ваш сервер должен быть в состоянии обрабатывать производственную информацию. подписанное приложение получает квитанции из тестовой среды Apple. Рекомендуемый подход заключается в том, чтобы ваш рабочий сервер всегда сначала проверял поступления в рабочем магазине приложений. Если проверка завершается неудачей с кодом ошибки «Квитанция из песочницы, используемая в рабочей среде», вам следует вместо этого проверить ее в тестовой среде.
Вот вся моя покупка в приложении. класс
Код: Выделить всё
import StoreKit
import SystemConfiguration
class InAppPurchaseManager: NSObject, SKPaymentTransactionObserver, SKProductsRequestDelegate {
static let shared = InAppPurchaseManager()
var productRequest: SKProductsRequest?
var products: [SKProduct]!
override init() {
super.init()
SKPaymentQueue.default().add(self)
}
func unlockContent() {
adsRemoved = true
TitleScreen.shared.removeAdsButton.isHidden = true
GameViewController.shared.bannerView.isHidden = true
SavedSettings.shared.setAdsSettings()
}
func isInternetAvailable() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
func fetchProducts() {
let productIdentifiers = Set(["remove_ads"])
productRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productRequest?.delegate = self
productRequest?.start()
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
self.products = response.products
if let product = products.first {
print("Fetched product: \(product.productIdentifier)")
} else {
print("Failed to fetch product")
}
}
// These two methods below are to request a purchase/restore which are called from TitleScreen buttons "removeAdButton" and "restorePurchases"
func requestPurchase() {
if isInternetAvailable() {
if let product = InAppPurchaseManager.shared.products.first(where: { $0.productIdentifier == "remove_ads" }) {
Task {
do {
try await InAppPurchaseManager.shared.purchase(product)
} catch {
print("Failed to initiate purchase: \(error)")
}
}
}
} else {
print("No internet connection available")
GameViewController.shared.showAlert(title: "Failure", message: "No internet connection available")
}
}
func restorePurchases() {
SKPaymentQueue.default().restoreCompletedTransactions()
}
func purchase(_ product: SKProduct) async throws {
print("request called")
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
print("Transaction Successful: \(transaction.payment.productIdentifier)")
unlockContent()
verifyReceipt()
SKPaymentQueue.default().finishTransaction(transaction)
case .failed:
print("Transaction Failed: \(transaction.error?.localizedDescription ?? "Unknown error")")
SKPaymentQueue.default().finishTransaction(transaction)
case .restored:
print("Transaction Restored: \(transaction.payment.productIdentifier)")
unlockContent()
verifyReceipt()
SKPaymentQueue.default().finishTransaction(transaction)
case .deferred:
print("Transaction Deferred: \(transaction.payment.productIdentifier)")
default:
break
}
}
}
func refreshReceipt() {
let receiptRefreshRequest = SKReceiptRefreshRequest()
receiptRefreshRequest.start()
}
func verifyReceipt() {
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
} catch {
print("Couldn't read receipt data with error: " + error.localizedDescription)
}
}
}
}
Если кто-то может помочь, я был бы очень признателен, я' Я сейчас понятия не имею.
Подробнее здесь: https://stackoverflow.com/questions/787 ... -what-im-d
Мобильная версия