I have the following methods called when I tap on the 'More' tab, which fetches my in-app purchase:
Once the in-app purchase product has been retrieved, a buy button is displayed (lines 35 - 47) in a table cell row if it hasn't already been bought. Like so:
Sometimes the products array contains the in-app purchase and everything's fine. Most of the time the reload method never gets beyond line 7. The products array is then accessed by the table method and finds a nill value, and crashes.
Code Block override func viewWillAppear(_ animated: Bool) { reload() loadDB() } func reload() { print("in reload in moreView!") HyperpolyglotShopping.store.requestProducts{ [weak self] success, products in print("success in reload in moreView is: \(success)") guard let self = self else { return } if success { self.products = products! } } }
Once the in-app purchase product has been retrieved, a buy button is displayed (lines 35 - 47) in a table cell row if it hasn't already been bought. Like so:
Code Block func tableView(_ moreTable: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var moreViewCell = UITableViewCell() switch indexPath.section { case 0: let contactCell = moreTable.dequeueReusableCell(withIdentifier: contactReuseIdentifier, for: indexPath) as? ContactTableCell contactCell?.imageContactCell?.image = UIImage(named: contactRowIcons[indexPath.row]) contactCell?.labelContactCell?.text = contactRowOptions[indexPath.row] moreViewCell = contactCell! case 1: let settingsCell = moreTable.dequeueReusableCell(withIdentifier: settingsReuseIdentifier, for: indexPath) as? SettingsTableCell settingsCell?.delegate = self settingsCell?.indexPath = indexPath settingsCell?.labelSettingsCell?.text = settingsRowOptions[indexPath.row] settingsCell?.imageSettingsCell?.image = UIImage(named: settingsRowOptionIcons[indexPath.row]) settingsCell?.buttonSettingsCell?.setTitle(settingsRowOptionButtons[indexPath.row], for: .normal) switch settingsCell?.indexPath.row { case 0: if languages?.count ?? 0 == 0 { settingsCell?.buttonSettingsCell?.isEnabled = false } else { settingsCell?.buttonSettingsCell?.isEnabled = true } case 1: let wordsWithTestScores = words?.filter { $0.languageCorrectAnswers > 0 || $0.homeworkCorrectAnswers > 0 || $0.bonusCorrectAnswers > 0 } if wordsWithTestScores?.count == 0 { settingsCell?.buttonSettingsCell?.isEnabled = false } else { settingsCell?.buttonSettingsCell?.isEnabled = true } default: break } moreViewCell = settingsCell! case 2: let purchaseCell = moreTable.dequeueReusableCell(withIdentifier: purchaseReuseIdentifier, for: indexPath) as? ProductTableCell print("products in tableView(_cellForRowAt) in moreView are: \(products)") let product = products[indexPath.row] purchaseCell?.product = product purchaseCell?.buyButtonHandler = { product in HyperpolyglotShopping.store.buyProduct(product) } moreViewCell = purchaseCell! default: break } return moreViewCell }
Sometimes the products array contains the in-app purchase and everything's fine. Most of the time the reload method never gets beyond line 7. The products array is then accessed by the table method and finds a nill value, and crashes.