it-swarm.com.ru

Приложение не обрабатывает погашение промо-кода покупки в приложении расходных материалов

В мое приложение встроена покупка в приложении (я следовал этому учебник ), функционал покупки работает. Однако, когда я выкупаю промо-код в App Store для одного из продуктов для покупок в приложении, мое приложение не отвечает на него. Даже в App Store сказано, что продукт был успешно выкуплен, мое приложение не отвечает на него.

Кто-нибудь проверял покупку в приложении, может ли ваше приложение обрабатывать промо-код? Не могли бы вы поделиться решением?

Я начал с этого:

override func viewDidLoad() {
    NotificationCenter.default.addObserver(self,
        selector: #selector(applicationDidBecomeActive(notification:)),
        name: NSNotification.Name.UIApplicationDidBecomeActive,
        object: nil
    )
}

func applicationDidBecomeActive(notification: NSNotification){
    let store = IAPHealper()

    //what needs to be put here?
}


extension IAPHelper: SKPaymentTransactionObserver {

    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch (transaction.transactionState) {
            case .purchased:
                completeTransaction(transaction)
                break
            case .failed:
                failedTransaction(transaction)
                break
            case .restored:
                restoreTransaction(transaction)
                break
            case .deferred:
                break
            case .purchasing:
                break
            }
        }
    }

    fileprivate func completeTransaction(_ transaction: SKPaymentTransaction) {
        print("completeTransaction...")
        deliverPurchaseNotificatioForIdentifier(transaction.payment.productIdentifier)
        defaultQueue.finishTransaction(transaction)
        purchaseCompletionHandler?(true, transaction)
    }

    fileprivate func restoreTransaction(_ transaction: SKPaymentTransaction) {
        guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }

        print("restoreTransaction... \(productIdentifier)")
        deliverPurchaseNotificatioForIdentifier(productIdentifier)
        defaultQueue.finishTransaction(transaction)
    }

    fileprivate func failedTransaction(_ transaction: SKPaymentTransaction) {
        print("failedTransaction...")

        if transaction.error!._code != SKError.paymentCancelled.rawValue {
            print("Transaction Error: \(String(describing: transaction.error?.localizedDescription))")
            purchaseCompletionHandler?(false, transaction)
        }

        defaultQueue.finishTransaction(transaction)
    }

    fileprivate func deliverPurchaseNotificatioForIdentifier(_ identifier: String?) {
        guard let identifier = identifier else { return }
        purchasedProductIdentifiers.insert(identifier)
        //NSNotificationCenter.defaultCenter().postNotificationName(IAPHelper.IAPHelperPurchaseNotification, object: identifier)
    }

    public func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]){
        print("Removed from queue.")
        print(transactions)
    }
}

Благодарю.

17
zsong

@ Eatton предоставил очень полезную информацию о другом тема . Я просто хочу подвести итог решения по выкупу промокода для расходных материалов.

I. Вы должны использовать SwiftyStoreKit и поместить этот код в AppDelegate:

SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
    for purchase in purchases {
        switch purchase.transaction.transactionState {
        case .purchased, .restored: 
            if purchase.needsFinishTransaction {
                SwiftyStoreKit.finishTransaction(purchase.transaction)
            }
            // Unlock content
            self.unlockIAPContent(productID: purchase.productId)
        case .failed, .purchasing, .deferred:
            break // do nothing
        }
    }
}

II. Если вы хотите вызвать логику в любом ViewController, рассмотрите возможность использования NotificationCenter , поместите код в // Разблокируйте контент

III. Как это проверить?

В выпуске iOS 11 Apple представила новую функцию для продвижение покупки в приложении прямо в App Store.

Сначала добавьте обработчик:

#if DEBUG
SwiftyStoreKit.shouldAddStorePaymentHandler = { payment, product in
    return true
}
#endif

Затем создайте следующий URL на вашем Mac, а затем перенесите его на устройство iOS и откройте его в Safari .

itms-services://?action=purchaseIntent&bundleId=com.example.app&productIdentifier=product_name

Тогда будет запущен блок завершения SwiftyStoreKit.completeTransactions() в вашем AppDelegate.

Это также можно использовать для проверки погашения промокода, поскольку запрос URL создает ожидающую транзакцию и добавляет ее в очередь. Убедитесь, что вы удалили этот код для выпуска вашего продукта.

Надеюсь это поможет!

0
zsong

Кроме того, что говорит Эндрю (о промо-кодах, работающих только в производственных средах), у вас может возникнуть проблема с механизмами обработки покупок приложений.

Вы должны инициализировать объект обработки покупок в AppDelegate, чтобы он немедленно получал ожидающие покупки и только что созданные покупки (или в этом случае, когда код погашен)

Если вы посмотрите примеры, показанные здесь:

https://developer.Apple.com/library/content/technotes/tn2387/_index.html#//Apple_ref/doc/uid/DTS40014795-CH1-BEST_PRACTICES-ADD_A_TRANSACTION_QUEUE_OBSERVER_AT_APPLICATION_LAUNCH

Вы на самом деле делаете то, что НЕ рекомендуется Apple.

Вместо этого добавьте обозреватель StoreKit ВНУТРИ своего AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate {
                           ....
    // Attach an observer to the payment queue.
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Attach an observer to the payment queue.
        SKPaymentQueue.default().add(your_observer)
        return true
    }

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

    // OTHER STUFF...

}

Из-за этого у вас может не хватать времени, когда ваше приложение получает покупки.

Между прочим, у вас уже есть вспомогательный объект "В покупках приложения" (IAPHealper). Все, что вам нужно сделать, - это сделать так, чтобы ваш AppDelegate сохранял в нем переменную и создавал ее экземпляр в методе didFinishLaunchingWithOptions.

Что-то вроде:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var store : IAPHealper;
                           ....
    // Attach an observer to the payment queue.
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        store = IAPHelper();

        return true
    }

    // OTHER STUFF...

}

Правка: (Чтобы сохранить всю информацию здесь о переполнении стека)

Согласно ответу сотрудника Apple: https://forums.developer.Apple.com/message/204476#204476

Промо-коды можно проверить только в производственном магазине.

Итак, чтобы проверить их:

  1. Отправьте свое приложение на рассмотрение приложения.
  2. Установите дату выхода приложения в будущем, чтобы после того, как приложение App Review одобрило приложение, оно не будет доступно обычному пользователю.
  3. Используйте промо-код приложения для установки приложения
  4. Используйте промо-код в приложении.

И, наконец, пост разработчика также предупреждает нас о том, что после утверждения приложения вы должны подождать 48 часов , прежде чем коды начнут работать.


Поэтому, если после выполнения описанных выше шагов ваше приложение будет работать не так, как ожидалось. Тогда проблема, с которой вы сталкиваетесь, заключается в том, что ваше приложение не "готово", когда Apple отправляет вам уведомление "Покупка успешно". Следовательно, почему вы должны следовать руководству, описанному в первой части этого ответа. (Об инициализации прослушивателя транзакций при запуске приложения)

5
Pochi

Промокоды работают только в производственной среде.

Если вы хотите, чтобы IAP работали без фактического выпуска приложения, используйте промо-коды, когда приложение находится в состоянии "ожидающий релиз разработчика" (после проверки). Один промо-код приложения для установки приложения и другой для тестирования IAP. Иногда может потребоваться дополнительное время (до 2 дней) для распространения данных по всем Apple серверам.

из официального ответа devforum

1
Andrew Veselov