1 Вопрос: Как StoreKit синхронизирует покупки на разных устройствах

вопрос создан в Thu, May 2, 2019 12:00 AM

Согласно документации Apple, «не расходные материалы синхронизируются между устройствами системой», или «не расходные материалы доступны для всех пользовательских устройств», или «StoreKit управляет процессом синхронизации и восстановления для не расходных материалов». К сожалению, я нигде не смог найти подробностей о механизме «синхронизации». Мое приложение сохраняет статус приобретенных непотребляемых продуктов в UserDefaults, которые являются локальными только по своей природе. Используя то же приложение на другом устройстве и нажав кнопку «Восстановить», я не получаю ни одной из моих предыдущих покупок. Итак, мои вопросы: что означает Apple, говоря о синхронизации между устройствами? Что нужно добавить в мое приложение, чтобы синхронизировать покупки на разных устройствах?

Код для кнопки восстановления :

public func restorePurchases() {    
    SKPaymentQueue.default().restoreCompletedTransactions()
}

И у меня есть расширение:

extension IAPHelper: SKPaymentTransactionObserver {
    // Called when a transaction states change
    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch (transaction.transactionState) {
            case .purchased:
                complete(transaction: transaction)
                break
            case .failed:
                fail(transaction: transaction)
                break
            case .restored:
                restore(transaction: transaction)
                break
            case .deferred:
                break
            case .purchasing:
                break
            }
        }
    }

И код для восстановления:

private func restore(transaction: SKPaymentTransaction) {
    guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }        
    print("restore... \(productIdentifier)") 
    deliverPurchaseNotificationFor(identifier: productIdentifier)
    SKPaymentQueue.default().finishTransaction(transaction)
}

И для deliveryPurchaseNotificationFor:

private func deliverPurchaseNotificationFor(identifier: String?) {
    guard let identifier = identifier else { return }
    purchasedProductIdentifiers.insert(identifier)
    let defaults = UserDefaults.standard
    var currentStatus = defaults.string(forKey:identifier)
    currentStatus = "Purchased"   // acheté mais pas sauvé
    defaults.set(currentStatus, forKey: identifier)
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "IAPHelperPurchaseNotification"), object: identifier)
}
    
- 1
  1. Хорошо, теперь мы кое-что получаем. Итак, когда вы нажимаете восстановление, что происходит? Распечатывается ли какое-либо из ваших утверждений print? Если нет, поставьте точку останова: работает ли какой-либо ваш код? Если да, то как далеко это продвинется?
    2019-05-02 16: 37: 50Z
  2. Кстати, неправильно использовать строку в качестве object в уведомлении. Если у вас есть информация для связи с получателем, это то, для чего нужен userInfo.
    2019-05-02 16: 39: 17Z
  3. Вы говорите: «Код для кнопки« Восстановить »: public func restorePurchases()» Это не имеет смысла. Что заставило бы кнопку вызывать этот код ? Это не @IBAction, и Objective-C не может увидеть его, так как он не помечен @objc. Пожалуйста, покажите, что действительно происходит , когда нажимается кнопка .
    2019-05-02 16: 40: 48Z
  4. на первом устройстве Restore дает мне 14 старых купленных предметов (все, что я купил в тестах). На втором устройстве, где я еще не купил, Restore ничего не дает.
    2019-05-02 16: 44: 59Z
  5. Я не копировал весь текст, но это функция действия //Bouton Restore tappé @IBAction func restoreTapped (_ sender: UIBarButtonItem) {print ("entrée dans restoreTapped ") MyBridgeStoreProducts.store.restorePurchases ()}
    2019-05-02 16: 48: 15Z
1 ответ                              1                         

Проблема, скорее всего, в этой строке:

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

Похоже, что это не удастся. Просто напишите

let productIdentifier = transaction.payment.productIdentifier 
    
0
2019-05-02 18: 43: 41Z
источник размещен Вот