2017-06-02 44 views
13

我的应用内置了应用内购买功能(我遵循此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) 
    } 
} 

感谢。

+0

请继续扔这个[视频](https://www.youtube.com/watch?v=dwPFtwDJ7tc)它会帮助你很多。 – Rex

回答

1

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

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

from official devforum answer

4

除了安德鲁说什么(约仅工作在生产环境中促销代码)看来你可能对您的“应用内购买”处理机制的问题。

你应该把你的购买处理对象初始化在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

你实际上做的是不推荐苹果。

而是添加StoreKit观察者INSIDE 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... 

} 

你实际上可能会在定时您的应用程序丢失接收购买因为这个原因。

顺便说一下,您已经有了“In App Purchases”辅助对象(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 = IAPHealper(); 

     return true 
    } 

    // OTHER STUFF... 

} 

编辑:(为了让这里所有的信息在堆栈溢出)

根据苹果的员工回应: https://forums.developer.apple.com/message/204476#204476

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

因此,为了对它们进行测试:

  1. 提交您的应用程序的应用程序审查。
  2. 设置应用程序在未来的发布日期,以便一旦App Review批准该应用程序,它不适用于一般用户。
  3. 使用应用程序促销代码来安装应用程序
  4. 使用应用程序促销代码。

最后,开发商的帖子也提醒我们,后一个应用程序已经被批准,你必须等待48小时代码开始工作之前。


因此,如果在按照上述步骤执行操作后,您的应用程序无法按预期运行。然后,当Apple向您发送“购买成功”通知时,您遇到的问题是您的应用程序未“准备就绪”。因此,为什么你应该遵循这个答案的第一部分描述的准则。 (关于一旦你的应用程序启动,初始化你的交易监听器)

+0

不起作用。你有没有试过你的解决方案?基本上,该解决方案适用于应用内购买,但它不适用于促销代码兑换。 – zsong

+0

问题是,应用内促销代码与“应用内购买”完全相同。不过,他们会遵循应用逻辑,在应用启动时“接收”成功的购买通知。因此,如果您已经按照此处提供的步骤操作:https://forums.developer.apple.com/message/204476#204476,但它仍然无法使用,这意味着“成功”购买通知正在丢失,因为您的应用程序是“未准备好”,因此为什么我写了如何正确配置应用程序购买以接收App Launch上的通知的说明。 – Pochi

+0

@zsong Apple的员工回应说同样的事情: “如果在SKProductsRequest工作后in_app促销代码没有激活,我会在启动时验证transactionObserver处于活动状态。” – Pochi