Tarvo Mäesepp Tarvo Mäesepp - 2 months ago 18
Swift Question

Comparing non optional value leads to error

I am on point where I gotta compare non optional value with nil. But I can't do it because Xcode says:


Comparing non-optional value of type 'Int' to nil always returns false


So I created Struct and then made variable:
var products: [Product] = []


How I am able to compare it with nil?:

if products[indexPath.row].snusPortions == nil
{
cell.snusPortionsAmountLabel.text = "N/A"
}else
{
cell.snusPortionsAmountLabel.text = String(products[indexPath.row].snusPortions)

}


I've assigned values to them like this:

let ref = FIRDatabase.database().reference().child("Snuses").queryOrdered(byChild: "Brand").queryEqual(toValue: brandName)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists(){

let enumerator = snapshot.children

while let thisProduct = enumerator.nextObject() as? FIRDataSnapshot
{
print(thisProduct.value) // So I may see what the data is like and know how to extract it

// Chances are you'd have to create a dictionary
let thisProductDict = thisProduct.value as! [String:AnyObject]

let productName = thisProductDict["Products"] as! String

let snusPortions = thisProductDict["PortionsCan"] as? Int

let productObject = Product(snusProductTitle: productName, snusNicotine: snusNicotine, snusPortions: snusPortions!, snusFlavor: snusFlavor, snusWeight: snusWeight!, snusShippingWeight: snusShippingWeight, snusProductImageURL: productURL)
self.products.append(productObject)
print(self.products)

}

self.tableView.reloadData()

}
})


This is Product struct:

struct Product {
var snusProductTitle: String, snusNicotine: Double, snusPortions: Int, snusFlavor: String, snusWeight: Double, snusShippingWeight: Int, snusProductImageURL: String, snusProductImage = UIImage()

init()
{
snusProductTitle = ""
snusNicotine = 0.0
snusPortions = 0
snusFlavor = ""
snusWeight = 0.0
snusShippingWeight = 0
snusProductImageURL = ""
snusProductImage = UIImage()
}

init(snusProductTitle: String, snusNicotine: Double, snusPortions: Int, snusFlavor: String, snusWeight: Double, snusShippingWeight: Int, snusProductImageURL: String, snusProductImage: UIImage = UIImage()){

self.snusProductTitle = snusProductTitle
self.snusNicotine = snusNicotine
self.snusPortions = snusPortions
self.snusFlavor = snusFlavor
self.snusWeight = snusWeight
self.snusShippingWeight = snusShippingWeight
self.snusProductImageURL = snusProductImageURL
self.snusProductImage = snusProductImage
}

}


While testing it says
snusPortions
is
nil
but I said to make it "N/A" if it is nil, why?

Answer

It sounds like you are confusing yourself between the local variable snusPortions and the Product property snusPortions.

In your Product definition, the property snusPortions is an Int. It can never be nil. Hence, in this code:

if products[indexPath.row].snusPortions == nil

... this Product's snusPortions will never be nil, and we will never set the text to "N/A".

Now let's look at your other code:

let snusPortions = thisProductDict["PortionsCan"] as? Int

This is a completely different snusPortions. It can be nil, namely, if thisProductDict lacks a "PortionsCan" key or if its value is not castable to Int.