如何在iOS 11中处理应用内购买的应用商店付款? [英] How to handle shouldAddStorePayment for In-App Purchases in iOS 11?

查看:1212
本文介绍了如何在iOS 11中处理应用内购买的应用商店付款?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施新的 paymentQueue( _:shouldAddStorePayment:for:) 方法,以便我的应用程序可以直接从App Store处理IAP。

I'm trying to implement that new paymentQueue(_:shouldAddStorePayment:for:) method so my app can handle IAPs directly from the App Store.

我正在使用 itms-services:// url来测试它,就像它说这里

I'm using the itms-services:// url to test it, like it says here.

事情是,我的 SKPaymentTransactionObserver 是一个特定的视图控制器,如果在我打开 itms-services:// 链接时它不可见,则委托方法赢了不被打电话。

The thing is, my SKPaymentTransactionObserver is a specific view controller, and if it's not visible when I open the itms-services:// link the delegate method won't be called.

我该怎么办?我想我必须检测用户是否来自App Store推送正确的视图控制器,但我不知道如何。我现在能想到的唯一另一个选择是让App Delegate成为 SKPaymentTransactionObserver ,但这看起来真的很麻烦,当我试用它时我无法让它工作。还有其他办法吗?

What can I do about that? I think I'd have to detect if the user is coming from the App Store to push the right view controller, but I don't know how. The only other option I can think of right now is to make the App Delegate an SKPaymentTransactionObserver, but that seems really cumbersome and I couldn't get it to work when I tried it. Is there any other way?

推荐答案

这是我所做的一个可以帮助你实现你想要的课程,只需复制下面的代码并将其粘贴到一个新文件中,然后您只需将 StoreManager.shared 类访问到您想要访问的任何方法/变量。

Here's a class I did that can help you achieve what you want, simply copy the code below and paste it inside a new file and then you can simply access the class StoreManager.shared to whatever method/variable you want to access.

1-要初始化此类,只需从 didFinishLaunchingWithOptions
StoreManager.shared.Begin()进行调用,然后添加付款观察员。

1- To init this class, just call from your didFinishLaunchingWithOptions StoreManager.shared.Begin() and then payment observer is added.

import Foundation
import StoreKit


class StoreManager: NSObject{



    /**
     Initialize StoreManager and load subscriptions SKProducts from Store
     */
    static let shared = StoreManager()

    func Begin(){
        print("StoreManager initialized".DubugText())
    }


    override init() {
        super.init()


        // Add pyament observer to payment qu
        SKPaymentQueue.default().add(self)


    }


    func requestProductWithID(identifers:Set<String>){

        if SKPaymentQueue.canMakePayments() {
            let request = SKProductsRequest(productIdentifiers:
                identifers)
            request.delegate = self
            request.start()


        } else {
            print("ERROR: Store Not Available")
        }


    }

    func buyProduct(product: SKProduct) {

        print("Buying \(product.productIdentifier)...")
        let payment = SKPayment(product: product)
        SKPaymentQueue.default().add(payment)


    }


    func restorePurchases(){

        SKPaymentQueue.default().restoreCompletedTransactions()
    }
    /*
     Instance variables

     */

}








// MARK:
// MARK: SKProductsRequestDelegate

//The delegate receives the product information that the request was interested in.
extension StoreManager:SKProductsRequestDelegate{

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {

        var products = response.products as [SKProduct]


        var buys = [SKProduct]()

        if (products.count > 0) {

            for i in 0 ..< products.count
            {
                let product = products[i]


                print("Product Found: ",product.localizedTitle)
            }


        } else {
            print("No products found")
        }

        let productsInvalidIds = response.invalidProductIdentifiers

        for product in productsInvalidIds
        {
            print("Product not found: \(product)")
        }
    }


    func request(_ request: SKRequest, didFailWithError error: Error) {
        print("Something went wrong: \(error.localizedDescription)")
    }
}



// MARK:
// MARK: SKTransactions


extension StoreManager: SKPaymentTransactionObserver {



    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch (transaction.transactionState) {
            case .purchased:
                completeTransaction(transaction: transaction)
                break
            case .failed:
                failedTransaction(transaction: transaction)
                break
            case .restored:
                restoreTransaction(transaction: transaction)
                break
            case .deferred:
                // TODO show user that is waiting for approval

                break
            case .purchasing:
                break
            }
        }
    }

    private func completeTransaction(transaction: SKPaymentTransaction) {

        print("completeTransaction...")

        deliverPurchaseForIdentifier(identifier: transaction.payment.productIdentifier)
        SKPaymentQueue.default().finishTransaction(transaction)
    }

    private func restoreTransaction(transaction: SKPaymentTransaction) {


        guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }

        print("restoreTransaction... \(productIdentifier)")


        deliverPurchaseForIdentifier(identifier: productIdentifier)
        SKPaymentQueue.default().finishTransaction(transaction)
    }

    private func failedTransaction(transaction: SKPaymentTransaction) {

        if let error = transaction.error as NSError? {
            if error.domain == SKErrorDomain {
                // handle all possible errors
                switch (error.code) {
                case SKError.unknown.rawValue:
                    print("Unknown error")

                case SKError.clientInvalid.rawValue:
                    print("client is not allowed to issue the request")


                case SKError.paymentCancelled.rawValue:
                    print("user cancelled the request")

                case SKError.paymentInvalid.rawValue:
                    print("purchase identifier was invalid")

                case SKError.paymentNotAllowed.rawValue:
                    print("this device is not allowed to make the payment")

                default:
                    break;
                }
            }


        }

        SKPaymentQueue.default().finishTransaction(transaction)
    }

    private func deliverPurchaseForIdentifier(identifier: String?) {

        guard let identifier = identifier else { return }


    }
}



//In-App Purchases App Store
extension StoreManager{

    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
        return true

        //To hold
        //return false

        //And then to continue
        //SKPaymentQueue.default().add(savedPayment)
    }

}

这篇关于如何在iOS 11中处理应用内购买的应用商店付款?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆