restoreCompletedTransactions () не работает - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь восстановить непотребляемый IAP с помощью SKPaymentQueue.default (). RestoreCompletedTransactions () и ничего не работает в соответствии с планом.В песочнице я получаю «Нет информации для покупок в приложении. Повторите попытку позже. 21105», а в Prod просто ничего не происходит.Из того, что я вижу, ошибка в Sandbox генерируется с фактической строкой SKPaymentQueue.default (). RestoreCompletedTransactions (), и после этого ничего не обрабатывается.Я уверен, что все правильно, так как я могу сделать свою покупку вручную, и она работает, я также могу выкупить что-нибудь снова с ошибкой, что у меня уже есть, и затем элемент активируется, но кнопка Восстановить не работает (restorePurchases ()),У меня есть 38 IAP в этом приложении, но я не уверен, связано ли это каким-либо образом, и все они не расходуемые.Это расширение iMessage, которое продает наклейки.Что также странно, это то, что Apple действительно откинула мое приложение назад, потому что я использовал свое собственное искусство без моего собственного разрешения (это было весело), ​​но все утверждают, что с Non-Consumable должна быть проверка Restore и Apple для этого, и в этомесли все прошло, пока оно не работает.

Мой класс IAP:

import Foundation
import StoreKit
import os.log


class IAPService: NSObject
{
    private override init() {} // make sure there is no extra copies

    static let shared = IAPService() // makes this singleton
    fileprivate var products = [SKProduct]()
    let paymentQueue = SKPaymentQueue.default()
    let defaults = UserDefaults.standard
    var haveData = false
    var reference = StickewrsCollectionViewController()
    fileprivate var request = SKProductsRequest()
    let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "IAPService")

    let receiptFetcher = ReceiptFetcher()


    func getProducts()
    {
        let allStickersIAP = “IAP reference”
        var iapList = Dictionary<String, String>()
        if let path = Bundle.main.path(forResource: "StickersData", ofType: ".plist")
        {
            let dict = NSDictionary(contentsOfFile: path) as! Dictionary<String, AnyObject>
            let globalData = dict["StickerData"] as! Array<AnyObject>
            iapList = (globalData[1]) as! Dictionary<String, String>
        }
        var products: Set = [allStickersIAP]
        for iap in iapList
        {
            products.insert(iap.value)
        }
        request = SKProductsRequest(productIdentifiers: products)
        request.delegate = self
        request.start()
        paymentQueue.add(self)
        SKPaymentQueue.default().add(self)
        os_log("Getting products")


    }

    func purchase(product: String)
    {
        if (SKPaymentQueue.canMakePayments())
        {
            guard let productToPurchase = products.filter({$0.productIdentifier == product}).first
            else {return}

            let payment = SKPayment(product: productToPurchase)
            paymentQueue.add(payment)
        }
    }

    func restorePurchases()
    {
        print("Restoring purchases")
        os_log("Restoring purchases")

        SKPaymentQueue.default().restoreCompletedTransactions()

    }

    func iapCheck() -> Bool
    {
        return SKPaymentQueue.canMakePayments() && haveData
    }

    func getProductData(iap: String) -> SKProduct
    {
        return products.filter({$0.productIdentifier == iap}).first ?? SKProduct()
    }

    func priceStringForProduct(item: SKProduct) -> String? {
        let price = item.price
        if price == NSDecimalNumber(decimal: 0.00) {
            return NSLocalizedString("free", comment: "") 
        } else {
            let numberFormatter = NumberFormatter()
            let locale = item.priceLocale
            numberFormatter.numberStyle = .currency
            numberFormatter.locale = locale
            return numberFormatter.string(from: price)
        }
    }

    func setReference(ref: StickewrsCollectionViewController)
    {
        reference = ref
    }

    public func passPopUp(_ text: String)
    {
        reference.ShowPopUp(text)
    }

    // Called when the application is about to terminate.
    func applicationWillTerminate(_ application: UIApplication) {
        // Remove the observer.
        SKPaymentQueue.default().remove(self)
    }

}

extension IAPService: SKProductsRequestDelegate, SKPaymentTransactionObserver
{
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        products = response.products

        haveData = true
    }

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
           switch  transaction.transactionState
            {
                case .purchasing: break
                case .purchased:
                    do {
                        defaults.set(true, forKey: transaction.payment.productIdentifier)
                        defaults.synchronize() // save changes in PlayerPrefs
                        print(transaction.payment.productIdentifier)
                        queue.finishTransaction(transaction)
                        }
            case .restored:
                do {
                    print("Do actual restoring")
                    os_log("Now restoring %@",  transaction.original!.payment.productIdentifier)
                    reference.ShowPopUp("Restoring purchase \(transaction.original!.payment.productIdentifier)")
                    defaults.set(true, forKey: transaction.original!.payment.productIdentifier)
                    defaults.synchronize() // save changews in PlayerPrefs
                    print(transaction.payment.productIdentifier)
                    queue.finishTransaction(transaction)
                }
                default: queue.finishTransaction(transaction)
            }
        }
        reference.redrawnAfterPurchase()
    }

    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        for transaction in queue.transactions {
            let t: SKPaymentTransaction = transaction
            let prodID = t.payment.productIdentifier as String

            defaults.set(true, forKey: prodID)
            defaults.synchronize() // save changews in PlayerPrefs
            print(prodID)
            queue.finishTransaction(transaction)
        }
        reference.redrawnAfterPurchase()
        reference.ShowPopUp(NSLocalizedString("restoreCompleted", comment: ""))
    }

}

extension SKPaymentTransactionState
{
    func status() -> String
    {
        switch self {
        case .deferred: return "deferred"
        case .failed: return "failed"
        case .purchased: return "purchased"
        case .purchasing: return "purchasing"
        case .restored: return "restored"

        }
    }
}

Что я сделал не так и как я могу заставить RestorePurchases действительно что-то делать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...