Swift3 应用程序没有';t办理消费品应用内购买促销代码的赎回

Swift3 应用程序没有';t办理消费品应用内购买促销代码的赎回,swift3,in-app-purchase,promotion-code,Swift3,In App Purchase,Promotion Code,我的应用程序内置了应用内购买功能(我遵循了这一点),购买功能可以正常工作。但是,当我在App Store中将促销代码兑换为某个应用内购买产品时,我的应用程序不会对此作出响应。即使应用商店表示产品已成功兑换,我的应用程序也没有响应 是否有人测试过你的应用程序是否可以处理促销代码?你介意分享一下解决方案吗 我从这个开始: override func viewDidLoad() { NotificationCenter.default.addObserver(self, sel

我的应用程序内置了应用内购买功能(我遵循了这一点),购买功能可以正常工作。但是,当我在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)
    }
}

谢谢。

促销代码仅适用于生产环境

若您想确保IAP在没有实际应用程序发布的情况下工作,那个么当应用程序处于“挂起的开发人员发布”状态时(在审查之后),请使用促销代码。一个应用程序促销代码用于安装应用程序,另一个用于测试IAP。有时,为所有苹果服务器分发数据可能需要额外的时间(最多2天)


除了Andrew所说的(关于仅适用于生产环境的促销代码),您可能在“应用程序购买”处理机制方面存在问题

您应该在AppDelegate中初始化您的purchases处理对象,以便它立即接收挂起的购买和刚刚创建的购买(或者在本例中,当代码被兑换时)

如果您检查此处显示的示例:

你实际上在做苹果不推荐的事情

而是将StoreKit observer添加到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...

}
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
        }
    }
}
因此,您可能实际上错过了应用程序接收购买的时间

顺便说一下,您已经有了一个“应用内购买”帮助对象(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...

}

编辑:(保留堆栈溢出的所有信息)

根据苹果公司员工的回复:

促销代码只能在生产商店进行测试

因此,为了测试它们:

  • 提交你的应用进行应用审查
  • 在将来的某个时候设置应用程序的发布日期,以便一旦应用程序审查批准应用程序,普通用户将无法使用该应用程序
  • 使用应用程序促销代码安装应用程序
  • 使用应用程序内促销代码
  • 最后,开发者的帖子还警告我们,在一个应用程序被批准后,你必须等待48小时,代码才能开始工作


    因此,如果在执行上述步骤后,您的应用程序的行为与预期不符。那么,当苹果向你发送“购买成功”通知时,你面临的问题是你的应用程序没有“准备就绪”。因此,为什么您应该遵循本答案第一部分所述的指南。(关于在应用程序启动后立即初始化事务侦听器)

    提供了非常有用的信息。我只想总结一下处理消费品促销代码兑换的解决方案

    I.您应该使用,并将此代码放入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...
    
    }
    
    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
            }
        }
    }
    
    二,。如果您想调用任何VIEW控制器中的逻辑,请考虑使用,将代码置于//解锁内容

    三、 如何测试它

    在iOS 11版本中,苹果推出了一项新功能,可直接在应用商店中使用

    首先添加处理程序:

    #if DEBUG
    SwiftyStoreKit.shouldAddStorePaymentHandler = { payment, product in
        return true
    }
    #endif
    
    然后在Mac上编写以下URL,将其空投到iOS设备并在Safari中打开

    然后将触发
    AppDelegate
    中的
    SwiftyStoreKit.completeTransactions()
    的完成块

    这也可以用于测试促销代码赎回,因为URL请求会创建一个挂起的事务并将其添加到队列中。请确保删除prod版本的此代码


    希望这有帮助

    请继续扔这个,它会帮你很多忙的,不行。你试过你的解决方案吗?基本上,解决方案适用于应用内购买,但不适用于促销代码兑换。问题是,应用内促销代码与“应用内购买”完全相同。但是,它们遵循应用程序启动时“接收”成功购买通知的逻辑。因此,如果您已经按照此处提供的步骤进行了操作:但它仍然不起作用,这意味着“成功”购买通知将丢失,因为您的应用程序在收到通知时“尚未准备就绪”,因此,我写了关于如何正确配置应用内购买以在应用启动时接收通知的说明。@zsong说,苹果公司的员工回复也是这样说的:“如果在SKProductsRequest工作后应用内促销代码没有激活,我会验证transactionObserver在启动时是否处于活动状态。”这250点是stackoverflow错误地存入的,解决方案实际上不起作用。谢谢你的努力。嗨,波奇。实际上,在阅读引用链接中提供的常见问题时,我看到“如果开发人员不批准将生产应用程序发布到应用商店,则不会激活任何新的应用程序内购买标识符”。据我所知,如果你的应用程序未发布,你无法通过SKProductRequest获得产品ID列表,因此你无法显示要购买的产品列表。理论上,2天是指开发人员发布后必须经过的时间。您是否收到了未发布应用程序的产品列表(例如,处于“待定开发人员发布”状态)?实际上,阅读引用链接中提供的常见问题,我发现“如果开发人员不批准将生产应用程序发布到应用商店,则不会激活任何新的应用程序内购买标识符”。因此,据我所知,如果您的应用程序处于“待定开发人员发布”状态,使用促销代码安装它,那么您无法通过SKProductRequest获得产品ID列表。理论上,2天是指开发者重新注册后必须经过的时间