Подтвердить что ты не робот

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

У моего приложения встроенная покупка в приложении (я следил за этим tutorial), работает функция покупки. Однако, когда я выкупаю промо-код в 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)
    }
}

Спасибо.

4b9b3361

Ответ 1

@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 и AirDrop переместите его на устройство iOS и откройте его в Safari.

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

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

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

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

Ответ 2

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

Вы должны инициализировать объект обработки покупок в 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 отправляет вам уведомление "Покупка успешно". Следовательно, почему вы должны следовать руководству, описанному в первой части этого ответа. (Об инициализации прослушивателя транзакций при запуске приложения)

Ответ 3

Промо-коды работают только в рабочей среде.

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

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