在显示按钮之前检查是不是可以进行应用内购买

Posted

技术标签:

【中文标题】在显示按钮之前检查是不是可以进行应用内购买【英文标题】:Check if In-App Purchase can be made before displaying the button在显示按钮之前检查是否可以进行应用内购买 【发布时间】:2017-08-25 22:46:20 【问题描述】:

我正在一个 XCode 项目中实现应用内购买,除了一个错误,一切正常。当用户未连接到 Internet 并单击购买按钮时,应用程序会崩溃。我相信发生这种情况是因为尚未从 iTunes 获取应用内购买,并且单击按钮无法运行购买过程。当用户在商店屏幕加载的第一秒点击按钮时也会发生这种崩溃,因为 - 我认为 - 需要一些时间来获取(或请求)产品。这就是我要说的:

override func didMove(to view: SKView) 
       ...
    fetchAvailableProducts()


func fetchAvailableProducts()  

    // Put here your IAP Products ID's
    let productIdentifiers = NSSet(objects:
        productID100,
        productID250,
        productID500,
        productIDRemoveAds,
        productIDUnlockAll)

    productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
    productsRequest.delegate = self
    productsRequest.start()


我的代码基于this tutorial。

有没有办法更改我的代码以使其“防崩溃”,以便它首先检查是否可以购买产品以让您使用按钮?

【问题讨论】:

提供崩溃的详细信息。听起来您没有使用产品的成功检索来启用您的ui @Paulw11 我所做的一切都像链接的教程一样。 对,所以教程代码是作为一个最小的例子编写的;在允许尝试购买之前,它不会检查产品是否已被检索;所以你会得到一个数组边界异常。您应该在产品请求委托方法中启用您的购买 UI @Paulw11 是的,这正是我想要做的。我该如何编码? 您最初会隐藏或禁用您的购买 UI,然后在 SKProductRequest(didReceive:) 中显示/启用它 【参考方案1】:

我使用 SwiftyStorkeKit (https://github.com/bizz84/SwiftyStoreKit),它使用完成处理程序来填充产品(也可以避免您重新发明*** - 并且是一个很好的学习资源)

至于检查网络连接,我使用 Apple 的 Reachability (https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html)。这是实现的相关部分。它还检查应用程序失去焦点的情况。您还可以在任何商店操作之前使用网络检查。

class vcon: UIViewController 
    @IBOutlet weak var noConnectionView: UIView!

    func isNetworkAvailable() -> Bool 
    //quick test if network is available
        var netTest:Reachability? = Reachability(hostName: "apple.com")!
        if netTest?.currentReachabilityStatus == .notReachable 
            netTest = nil
            return false
        
        netTest = nil
        return true
    

    func displayNoNetworkView() 
    //this example pulls from a storyboard to a view I have in front of everything else at all times, and shows the view to block everything else if the network isnt available

        let ncvc = UIStoryboard(name: "HelpPrefsInfo", bundle: nil).instantiateViewController(withIdentifier: "noNetworkVC") as! noNetworkVC
        ncvc.view.frame = noConnectionView.bounds
        ncvc.view.backgroundColor = color03
        ncvc.no_connection_imageView.tintColor = color01
        ncvc.noInternetConnection_label.textColor = color01
        noConnectionView.addSubview(ncvc.view)
    

    func hideDataIfNoConnection() 
//the actual code that displays the no net connection view
        if !isNetworkAvailable() 
            if noConnectionView.isHidden == true 
                noConnectionView.alpha = 0
                noConnectionView.isHidden = false
                self.iapObjects = []
                UIView.animate(withDuration: 0.50, animations: 
                    self.noConnectionView.alpha = 1
                , completion:(finished : Bool)  in
                );
            
         else 
            if noConnectionView.isHidden == false 
                self.collection_view.reloadData()
                UIView.animate(withDuration: 0.50, animations: 
                    self.noConnectionView.alpha = 0
                , completion:(finished : Bool)  in
                    self.noConnectionView.isHidden = true
                    self.loadIAPData()
                );
            
        

    

    override func viewDidLoad() 
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: .UIApplicationDidBecomeActive, object: nil)

        displayNoNetworkView()

        loadIAPData()

    

    func loadIAPData() 
load the data if the network is available

        if isNetworkAvailable() 

           helper.requestProductsWithCompletionHandler(completionHandler:  (success, products) -> Void in
                if success 
                    self.iapObjects = products!
                    self.collection_view.reloadData()
                 else 
                    let alert = UIAlertController(title: "Error", message: "Cannot retrieve products list right now.", preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                    self.present(alert, animated: true, completion: nil)
                
            )
        
    

   func willEnterForeground() 
        hideDataIfNoConnection()
    



    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)

        hideDataIfNoConnection()

    

【讨论】:

以上是关于在显示按钮之前检查是不是可以进行应用内购买的主要内容,如果未能解决你的问题,请参考以下文章

应用内购买恢复按钮

如何在应用内购买中恢复购买?

Android:应用内:检查是不是已购买商品

应用内购买实施

iOS - 应用内购买 - 恢复按钮?

应用内购买“创建”按钮已停用 iOS 应用内购买创建