ios - Swift / App Store:应用内购买问题
问题描述
我的应用程序有问题。在 ios 12,4 iphone 5s 上,我的应用内购买非常好用。但是当我在 Apple Store 发送二进制文件时,我得到了一个回报:“我们注意到您的应用程序仍然没有在应用程序中显示应用内购买产品的购买按钮。”。购买按钮仅在付款处理已准备就绪。在家里大约 2 到 3 秒。但是对于他们显然它根本不起作用......这是我的商店处理所有事情的完整代码。我指定使用我的 iphone 我设法拥有购买窗口并在沙盒中购买集成购买。
import UIKit
import StoreKit
import MessageUI
class ShopViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver, MFMailComposeViewControllerDelegate {
@IBOutlet weak var buyBtn: UIButton!
@IBOutlet weak var restore: UIButton!
@IBOutlet weak var mail: UIImageView!
@IBOutlet weak var shopDescription: UILabel!
var productsRequest = SKProductsRequest()
var validProducts = [SKProduct]()
var productIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
buyBtn.isHidden = true
shopDescription.numberOfLines = 0
shopDescription.lineBreakMode = NSLineBreakMode.byWordWrapping
shopDescription.sizeToFit()
shopDescription.text = NSLocalizedString("packpro", comment: "")
// SKPaymentQueue.default().add(self)
let tap4 = UITapGestureRecognizer(target: self, action:#selector(tappedMe5))
mail.addGestureRecognizer(tap4)
mail.isUserInteractionEnabled = true
fetchAvailableProducts()
}
func fetchAvailableProducts() {
let productIdentifiers = NSSet(objects:
"customLifePremium" // 0
)
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
productsRequest.delegate = self
productsRequest.start()
}
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
validProducts = response.products
let prod100coins = response.products[0] as SKProduct
print("1st rpoduct: " + prod100coins.localizedDescription)
buyBtn.isHidden = false
}
}
/* func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
return true
}*/
func canMakePurchases() -> Bool { return SKPaymentQueue.canMakePayments() }
func purchaseMyProduct(_ product: SKProduct) {
if self.canMakePurchases() {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
} else { print("Purchases are disabled in your device!") }
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
UserDefaults.standard.set(true, forKey: "premiumUser")
UserDefaults.standard.set(false, forKey: "limitedVersion")
break
case .failed:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
print("Payment has failed.")
break
case .restored:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
print("Purchase has been successfully restored!")
UserDefaults.standard.set(true, forKey: "premiumUser")
UserDefaults.standard.set(false, forKey: "limitedVersion")
break
default: break
}}}
}
func restorePurchase() {
SKPaymentQueue.default().add(self as SKPaymentTransactionObserver)
SKPaymentQueue.default().restoreCompletedTransactions()
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
print("The Payment was successfull!")
}
override func viewWillAppear(_ animated: Bool) {
setGradientBackground()
super.viewWillAppear(animated)
}
@IBAction func restoreCC(_ sender: Any) {
restorePurchase()
}
@IBAction func buyCC(_ sender: Any) {
productIndex = 0
purchaseMyProduct(validProducts[productIndex])
}
@objc func tappedMe5()
{
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setToRecipients(["dfmv.enterprise@gmail.com"])
mail.setSubject("")
mail.setMessageBody("", isHTML: true)
present(mail, animated: true)
}else{
let alert = UIAlertController(title: NSLocalizedString("info", comment: ""), message: NSLocalizedString("noClientMail", comment: ""), preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("ok", comment: ""), style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func setGradientBackground() {
let colorTop = UIColor(red:1.00, green:0.30, blue:0.30, alpha:1.0).cgColor
let colorBottom = UIColor(red:1.00, green:0.69, blue:0.25, alpha:1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at:0)
}
}
解决方案
查看我个人一周前使用的这个 Gist,并通过了 AppStore 对 In-App Purchase 流程的审查。
Swift 5中的IAP服务:
https://gist.github.com/egzonpllana/abd6d385bb45b1e329fe85a624ee531f
您可以调用IAPService.shared.getProducts()
AppDelegate 方法:didFinishLaunchingWithOptions
要在任何视图控制器中从 StoreKit 中准备好所有产品,只需检查IAPService.shared.products.count
.
或者在 viewDidLoad 中调用您的特定视图控制器并通过以下方式监听更改:IAPService.shared.didFinishRetrievingProducts = { [ weak self ] in ... }
推荐阅读
- video - 如何修复 MJPEG 文件中的 fps/持续时间信息
- python - nbconvert doesn't respect jupyter center alignment
- c++ - what is a simple way to run many similar queries concurrently in SQLite in c++?
- docker - 使用 Compose 和 Github 操作部署 Docker 容器
- ruby-on-rails - 复杂的时间转换和阶段划分留下错误
- python - 我可以只显示我的 MonkeyLearn 模型中的 tag_name 吗?
- javascript - 如何将类添加到传递的组件
- c# - JwtSecurityToken 过期时间无效 .NET Core 3.1
- anylogic - 使用 createAndStart 的目的
- java - 如何使用 Java 中的当前登录信息访问安全网站