title: (Swift) In-App Purchase - SKProductResquest is 0 (nil)
body: <p>Good afternoon </p>
  
  <p>Obs: I use the Rechiability class to check if the user internet is connected or not but in this case the class verify the internet but i dont receive the information from apple.
  So I know this is giving unwrapping nil value because in the productRequest method the response.products is not receiving any product, however it is only in the case below.</p>
  
  <p>I created a payment system and it works fine, however there is a case that it is crashing which is:</p>
  
  <p>1 User enters app without internet connection (Wi-Fi or 4G).</p>
  
  <p>2 User tries to buy the app offline and gets into the purchase viewcontroller.</p>
  
  <p>3 Press the iphone HOME button and then connect the Wi-Fi or 4G.</p>
  
  <p>4 After return to the app and press the button to purchase again and the crash appear.</p>
  
  <p>This only happens in this situation, in the other test cases I did not receive any errors.</p>
  
  <p>I can not see why this error occurred.</p>
  
  <p>Below is my code and images about the error.</p>
  
  <p>My current code:</p>
  
  <pre><code>import UIKit
  import StoreKit
  
  protocol IAPManagerDelegate 
  {
      func managerDidRestorePurchases()
  }
  
  class IAPManager: NSObject, SKProductsRequestDelegate,     SKPaymentTransactionObserver, SKRequestDelegate 
  {
  
  static let sharedInstance = IAPManager()
  
  var request:SKProductsRequest!
  var products:NSArray!
  
  //Load product identifiers for store usage
  func setupInAppPurchases()
  {
      self.validateProductIdentifiers(self.getProductIdentifiersFromMainBundle())
  
      SKPaymentQueue.default().add(self)
  }
  
  //Get product identifiers
  func getProductIdentifiersFromMainBundle() -&gt; NSArray 
  {
      var identifiers = NSArray()
      if let url = Bundle.main.url(forResource: "iap_product_ids", withExtension: "plist")
      {
          identifiers = NSArray(contentsOf: url)!
      }
  
      return identifiers
  }
  
  //Retrieve product information
  func validateProductIdentifiers(_ identifiers:NSArray) 
  {
  
      if Reachability.isConnectedToNetwork() == true
      {
          print("Enter")
          let productIdentifiers = NSSet(array: identifiers as [AnyObject])
          let productRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set&lt;String&gt;)
          self.request = productRequest
          productRequest.delegate = self
          productRequest.start()
      }
  
  }
  
  func createPaymentRequestForProduct(_ product:SKProduct)
  {
  
      if Reachability.isConnectedToNetwork() == true
      {
          let payment = SKMutablePayment(product: product)
          payment.quantity = 1
          SKPaymentQueue.default().add(payment)
      }
  }
  
  
  //MARK: SKProductsRequestDelegate 
  func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) 
  {
      //
      self.products = response.products as NSArray!
  
      for product in products
      {
          let temp = product as! SKProduct
  
          if temp.productIdentifier == "monthly.subscription"
          {
              print("price: \(temp.price)")
              formatProductMonth(free: temp)
          }
          if temp.productIdentifier == "weekly.subscription"
          {
              print("price: \(temp.price)")
              formatProductFree(free: temp)
          }
          if temp.productIdentifier == "yearly.subscription"
          {
              print("price: \(temp.price)")
              formatProductYear(free: temp)
          }
      }
      // print("Product[0]: \(string)")
      // print("Product[1]: \(prod1.productIdentifier)")
      // print("Product[2]: \(prod2.productIdentifier)")
  }
  
  //MARK: SKPaymentTransactionObserver Delegate Protocol
  func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) 
  {
  
  
      //
      for transaction in transactions as [SKPaymentTransaction]
      {
          switch transaction.transactionState
          {
              case .purchasing:
              print("Purchasing")
              UIApplication.shared.isNetworkActivityIndicatorVisible = true
              break
              case .deferred:
              print("Deferrred")
  
              let alertController: UIAlertController = UIAlertController(title: "Deferred", message: "Purchase deferred", preferredStyle: .alert)
              let dismiss = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
              alertController.addAction(dismiss)
              alertController.show()
              UIApplication.shared.isNetworkActivityIndicatorVisible = false
              break
              case .failed:
              print("Failed")
              //print(transaction.error?.localizedDescription)
              UIApplication.shared.isNetworkActivityIndicatorVisible = false
              SKPaymentQueue.default().finishTransaction(transaction)
              let alertController: UIAlertController = UIAlertController(title: "Failed", message: "Purchase failed", preferredStyle: .alert)
              let dismiss = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
              alertController.addAction(dismiss)
              alertController.show()
              //UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
              break
              case.purchased:
              StopActivator()
              print("Purchased")
              self.verifyReceipt(transaction)
              let thankyou = UserDefaults.standard.bool(forKey: "Purchased")
  
              if thankyou == true
              {
  
                  let alertController: UIAlertController = UIAlertController(title: "Thank You", message: "Purchase completed", preferredStyle: .alert)
                  let dismiss = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: { (action: UIAlertAction!) in
                  UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: true, completion: nil)
                  })
                  alertController.addAction(dismiss)
                  alertController.show()
  
              }
  
              break
              case .restored:
              print("Restored")
              let alertController: UIAlertController = UIAlertController(title: "Restore Success", message: "Your purchases have been restored", preferredStyle: .alert)
              let dismiss = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
              alertController.addAction(dismiss)
              alertController.show()
              break
  
          }
      }
  }
  </code></pre>
  
  <p>Pictures for the errors above:</p>
  
  <p><a href="https://i.stack.imgur.com/Lm5Nt.png" rel="nofollow noreferrer">First Image</a></p>
  
  <p><a href="https://i.stack.imgur.com/odAKH.png" rel="nofollow noreferrer">Second Image</a></p>
  
  <p>Please I know what is unwrapping an Optional Value "Obs: I use the Rechiability class to check if the user internet is connected or not but in this case the class verify the internet but i dont receive the information from apple. So I know this is giving unwrapping nil value because in the productRequest method the response.products is not receiving any product, however it is only in the case below."</p>
  
  <p>My question is why is giving this error in this case: " I created a payment system and it works fine, however there is a case that it is crashing which is: 1 User enters app without internet connection (Wi-Fi or 4G). 2 User tries to buy the app offline and gets into the purchase viewcontroller. 3 Press the iphone HOME button and then connect the Wi-Fi or 4G. 4 After return to the app and press the button to purchase again and the crash appear."</p>