我正在开发一款应用内购买的IOS应用程序。在通过USB进行调试时,应用内购买会显示在所有设备上,我可以购买。当部署到TestFlight并安装时,应用外购买会出现在iPhone上,但不会出现在iPad上。UI元素只是在特定场景中不加载。应用内购买是在app Store Connect中设置的,正如我所提到的,在iPhone上查看时会正确加载。
显示IAP:的视图代码
List(storeManager.myProducts, id: .self) { product in
HStack {
VStack(alignment: .leading) {
Text(product.localizedTitle)
.font(.headline)
Text(product.localizedDescription)
.font(.caption2)
}
Spacer()
if UserDefaults.standard.bool(forKey: product.productIdentifier) {
Text("Purchased")
.foregroundColor(.green)
} else {
Button(action: {
storeManager.purchaseProduct(product: product)
}) {
Text("Buy for (product.price) $")
}
.foregroundColor(.blue)
}
}
}
.navigationTitle("")
.toolbar(content: {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
storeManager.restoreProducts()
}) {
Text("Restore Purchases ")
}
}
})
.onAppear(perform: {
storeManager.myProducts = []
storeManager.getProducts(productIDs: productIDs)
})
仓库管理员代码:
class StoreManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
//FETCH PRODUCTS
var request: SKProductsRequest!
@Published var myProducts = [SKProduct]()
func getProducts(productIDs: [String]) {
print("Start requesting products ...")
let request = SKProductsRequest(productIdentifiers: Set(productIDs))
request.delegate = self
request.start()
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("Did receive response")
if !response.products.isEmpty {
for fetchedProduct in response.products {
DispatchQueue.main.async {
self.myProducts.append(fetchedProduct)
}
}
}
for invalidIdentifier in response.invalidProductIdentifiers {
print("Invalid identifiers found: (invalidIdentifier)")
}
}
func request(_ request: SKRequest, didFailWithError error: Error) {
print("Request did fail: (error)")
}
//HANDLE TRANSACTIONS
@Published var transactionState: SKPaymentTransactionState?
func purchaseProduct(product: SKProduct) {
if SKPaymentQueue.canMakePayments() {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
} else {
print("User can't make payment.")
}
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchasing:
transactionState = .purchasing
case .purchased:
UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
queue.finishTransaction(transaction)
transactionState = .purchased
case .restored:
UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
queue.finishTransaction(transaction)
transactionState = .restored
case .failed, .deferred:
print("Payment Queue Error: (String(describing: transaction.error))")
queue.finishTransaction(transaction)
transactionState = .failed
default:
queue.finishTransaction(transaction)
}
}
}
func restoreProducts() {
print("Restoring products ...")
SKPaymentQueue.default().restoreCompletedTransactions()
}
}
由于所有设备都可以通过USB调试正常工作,我不知道如何前进。有人遇到过这个问题吗?
请求委托在另一个线程上操作时,这似乎是线程问题。根据SKProductsRequestDelegate
:文件
SKProductsRequestDelegate收到的响应可能不会在特定线程上返回。如果假设哪个队列将处理委托响应,那么将来可能会遇到意外的性能和兼容性问题。
因此,如果您没有获得产品,则不会更新您的List
。尝试检查您的DispatchQueue
或Task
,并确保您没有对委托返回的线程做出任何假设。此外,如果使用Task
及其async/await API,请尝试使用DisptchQueue
,反之亦然。