在显示按钮

时间:2017-08-25 22:46:20

标签: ios swift in-app-purchase storekit

我正在XCode项目中实现应用程序内购买,除了一个错误外,一切正常。当用户未连接到互联网并且他点击购买按钮时,应用程序崩溃。我相信这是因为没有从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

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

1 个答案:

答案 0 :(得分:0)

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

至于检查网络连接,我使用Apple的可达性(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()

    }