警报确认应用内购买永远不会出现

问题描述 投票:1回答:1

我有通常的商店套件队列观察代码:

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出现?

ios swift in-app-purchase
1个回答
2
投票

问题

您已经开始关注应用内购买和StoreKit的严重时间和信息问题。

这里出了什么问题是你(商店观察员)收到paymentQueue(_:updatedTransactions:),那时两件事同时发生,导致竞争条件:

  • 运行时将其“You arere all set”警告。
  • 你试着把你的UIAlertController(并开始其他各种活动)。

正如你正确地说的那样,当用户解除运行时的“你已全部设置”警报时,你不会告诉你任何事件。那么在警报结束后你怎么办?

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

解决方案

解决方案是识别当系统的“你已全部设置”警报启动时,您的应用程序将被停用。我们可以检测到这一事实并注册,以便在您的应用再次激活时收到通知。那是用户解除“你已全部设置”警报的那一刻!

因此,您现在可以安全地提出UIAlertController警报。

像这样(使用我的delay实用程序,请参阅https://stackoverflow.com/a/24318861/341994; vc是视图控制器,我们将在上面显示警报):

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)
                }
            }
    }
}

我已经反复测试过这种方法(虽然很困难,因为测试商店套件的工作非常糟糕),而且看起来非常可靠。

© www.soinside.com 2019 - 2024. All rights reserved.