我有通常的存储套件队列观察器代码:

func paymentQueue(_ queue: SKPaymentQueue,
    updatedTransactions transactions: [SKPaymentTransaction]) {
        for t in transactions {
            switch t.transactionState {
            case .purchasing, .deferred: break // do nothing
            case .purchased, .restored:
                let p = t.payment
                if p.productIdentifier == myProductID {
                    // ... set UserDefaults to signify purchase ...
                    // ... put up an alert thanking the user ...
                    queue.finishTransaction(t)
                }
            case .failed:
                queue.finishTransaction(t)
            }
        }
}

问题是在我有“对用户表示感谢的警报”的评论时该怎么办。看起来很简单:我正在创建UIAlertController并调用present进行显示。但是它有时不出现!

麻烦似乎与运行时发出自己的警报(“您已经准备好”)有关。我对此没有任何通知,所以我不知道这种情况正在发生。如何确定我的UIAlertController出现?

最佳答案

问题

您已经开始认真考虑有关应用内购买和StoreKit的时间和信息问题。

出问题了,您(商店观察员)收到了paymentQueue(_:updatedTransactions:),此刻同时发生了两件事,导致了竞争状况:

  • 运行时显示“您已全部设置”警报。
  • 您尝试放置UIAlertController(并启动其他各种 Activity )。

  • 正确地说,当用户关闭运行时的“一切就绪”警报时,您不会收到任何事件来告诉您。那么,警报结束后您该怎么办?

    此外,如果您尝试在系统发出“您已全部设置”警报的同时发出警报,则您将无声地失败-UIAlertController警报将永远不会出现。

    解决方案

    解决方案是识别出系统“您已设置好”警报启动时,您的应用已停用。我们可以检测到这一事实,并注册以在再次激活您的应用时通知您。这就是用户取消“您已全部设置”警报的时刻!

    因此,现在放上UIAlertController警报是安全的。

    这样(使用我的delay实用程序,请参阅https://stackoverflow.com/a/24318861/341994vc是我们将在其顶部显示警报的视图控制器):
    let alert = UIAlertController( // ...
    // ... configure your alert here ...
    delay(0.1) { // important! otherwise there's a race and we can get the wrong answer
        if UIApplication.shared.applicationState == .active {
            vc.present(alert, animated:true)
        } else { // if we were deactivated, present only after we are reactivated
            var ob : NSObjectProtocol? = nil
            ob = NotificationCenter.default.addObserver(
                forName: UIApplication.didBecomeActiveNotification,
                object: nil, queue: nil) { n in
                    NotificationCenter.default.removeObserver(ob as Any)
                    delay(0.1) { // can omit this delay, but looks nicer
                        vc.present(alert, animated:true)
                    }
                }
        }
    }
    

    我已经反复测试了这种方法(尽管很困难,因为测试存储套件的东西效果很差),而且看起来完全可靠。

    关于ios - 提醒您确认应用内购买从未出现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55342218/

    10-14 20:25
    查看更多