나는 인앱 구매로 이미 며칠 동안 놀고 다음 호를 찾았습니다 (예상되는 동작인지 알려주십시오).인앱 구매가 다른보기 컨트롤러로 리디렉션 됨
현재 Apple Store가 아닌 TestFlight에서 응용할 수 있습니다.
사용자가 구매할 수있는 항목의 목록이 있으며 사용자가 "구매"를 탭하면 모든 정상적인 단계를 거칩니다. 즉, 제품이 선택되면 구매 확인 및 "제출"작업 완료시에 AlertViewController
을 표시합니다 AlertViewController
IAP Manager
에 buyProduct
으로 전화합니다. 그런 다음 [환경 : 샌드 박스] 등의 "인앱 구매 확인"대화 상자에 "취소/구매"에 대한 일반 대화 상자가 나타납니다.
그러나 "구매"를 탭하면 이전 View Controller로 리디렉션되고 "You '모든 설정'. 이전 View Controller에 표시됩니다.
TestFlight 버전에서 정상이면 괜찮습니다. 이것이 내가 애플 스토어에서해야 할 행동이라면, 수정이 필요하다. IAPManager를 호출
class IAPManager: NSObject {
static let sharedInstance = IAPManager()
static let IAPManagerPurchaseNotification = "IAPManagerPurchaseNotification"
fileprivate var productsRequest: SKProductsRequest?
fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler?
func initialize() {
SKPaymentQueue.default().add(self)
}
func deinitialize() {
SKPaymentQueue.default().remove(self)
}
/// Request products from Apple Store.
/// - parameter products: IAPProduct to purchase.
func requestProduct(products: [IAPProduct], _ completionHandler: @escaping ProductsRequestCompletionHandler) {
productsRequest?.cancel()
productsRequestCompletionHandler = completionHandler
var productIdentifiers: Set<String> = Set<String>()
for product in products {
productIdentifiers.insert(product.rawValue)
}
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productsRequest?.delegate = self
productsRequest?.start()
}
/// Does actual purchasing against Apple Store.
/// - parameter product: product that user wants to purchase.
func buyProduct(_ product: SKProduct) {
Log.info(message: "User \(UsersManager.sharedInstance.currentUserId) is purchasing \(product.productIdentifier)", sender: self)
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
class func canMakePayments() -> Bool {
return SKPaymentQueue.canMakePayments()
}
/// Restores previously purchased non-consumable items.
func restorePurchases() {
SKPaymentQueue.default().restoreCompletedTransactions()
}
}
extension IAPManager: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
Log.info(message: "Loaded list of products...", sender: self)
let products = response.products
productsRequestCompletionHandler?(true, products)
clearRequestAndHandler()
for p in products {
Log.info(message: "Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)", sender: self)
}
}
func request(_ request: SKRequest, didFailWithError error: Error) {
Log.error(message: "Failed to load list of products with error: \(error.localizedDescription)", sender: self)
productsRequestCompletionHandler?(false, nil)
clearRequestAndHandler()
}
private func clearRequestAndHandler() {
productsRequest = nil
productsRequestCompletionHandler = nil
}
}
extension IAPManager: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch (transaction.transactionState) {
case .purchased: complete(transaction: transaction)
case .failed: fail(transaction: transaction)
case .restored: restore(transaction: transaction)
case .deferred: Log.info(message: "Purchase is deffered", sender: self)
case .purchasing: Log.info(message: "Purchase is in progress", sender: self)
}
}
}
private func complete(transaction: SKPaymentTransaction) {
Log.info(message: "Purchase is completed.", sender: self)
deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
}
private func restore(transaction: SKPaymentTransaction) {
guard let productIdentifier = transaction.original?.payment.productIdentifier else {
return
}
Log.info(message: "Purchase \(productIdentifier) is in restore state.", sender: self)
deliverPurchaseNotificationFor(identifier: productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
}
private func fail(transaction: SKPaymentTransaction) {
Log.info(message: "Purchase is failed.", sender: self)
if let transactionError = transaction.error as NSError? {
if transactionError.code != SKError.paymentCancelled.rawValue {
Log.error(message: "Transaction Error: \(transactionError.localizedDescription)", sender: self)
}
}
SKPaymentQueue.default().finishTransaction(transaction)
}
private func deliverPurchaseNotificationFor(identifier: String?) {
guard let identifier = identifier else {
return
}
NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPManager.IAPManagerPurchaseNotification), object: identifier)
}
}
코드 :
let alert = UIAlertController(title: "<Title>", message: "<Message>", preferredStyle: .alert)
IAPManager.sharedInstance.requestProduct(products: [product]) { success, products in
guard success, let products = products, !products.isEmpty else {
Log.error(message: "Error occured during product request.", sender: self)
return
}
let product = products[0]
let submit = UIAlertAction(title: "Ok", style: .default) { action in
IAPManager.sharedInstance.buyProduct(product)
}
let cancel = UIAlertAction(title: "No", style: .destructive, handler: nil)
alert.addAction(submit)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
이것은 일반적인 동작이 아닙니다. @Array, 경고 기능을 확인하는 코드가 있습니다. –
아니요, 인앱 구매 관리자 – Array
Btw에서 코드가 업데이트되어 문제가 자체적으로 사라졌습니다. 어쩌면 다른 요인들 때문일 수도 있습니다. – Array