Get Rid Of Optionals in text

I'm trying to get rid of the optional words that I display with text in a tableview. What is wrong with my code?

if let experience = Int(theYears.text!) {
  theYears.text = "\(item?.experience)"
}
if let salary = Int(theSalary.text!) {
  theSalary.text = "\(item?.salary)"
}

Not sure what item is in this example without more context. But you used the if let experience... form to bind experience if it's not optional. Why not just do theYears.text = "\(experience)"?

item is accessing both experience and salary from a current player class so I need it.

item?.experience is referring to a property of item named experience, not to the local variable experience that you bound in the if let.

What are you using the let binding for, then? Sorry, I'm missing extra context so I'm working off the assumption that item.experience is the same value as Int(theYears.text!)! (and similarly for item.salary). If that's the case then you've already got a non-optional value to experience in the first if let clause, and you have salary in the second if let clause.

If my assumption is incorrect, then one quick hack you can quickly do to get rid of the "Optional" in the text is to change your strings to force unwrap item, like so: theYears.text = "\(item!.experience)".

Though I would recommend structuring things so that you're not force unwrapping with the ! operator so often. If you can, using a guard let item = item... clause further up in this scope can guarantee that you have item ahead of time. Then you don't need the ? or ! operators when asking values of it at all.

How would that look though for experience. Can you provide an example?

Ok, I'm afraid my example may not help in your case because there's not much context to go on. Your original example pulled text out of the text fields and then put the value right back into them. I'm not sure what that was supposed to achieve so I'm just going to assume that what you were trying to do was get the values out of an optional item value and set those as text in the text fields.

if let item = item {
  theYears.text = "\(item.experience)"
  theSalary.text = "\(item.salary)"
}
else {
  theYears.text = nil
  theSalary.text = nil
}

The if let statements will do the unwrapping of optionals for you and only execute their clause if you indeed have a value.

Hope that helps!

Postscript:
It might be useful to know that you could also do this inline the way you had it before by using the nil coelescing operator:

theYears.text = "\(item?.experience ?? "")"

The ?? acts like a fallback operator. If the lefthand side is nil, then the righthand side is used.

This is something I often want to write, but unfortunately it only works if the element on the left side of the ?? is also a string.

Ah, yeah that's necessary. In that case, just ensuring you've handled optionals farther up the stack will help.

Just use the description property if the type conforms to CustomStringConvertible, or create the String manually if not. "\(item.map(String(describing:)) ?? "Default"" Though String(describing:) isn't the greatest for UI, so a String property of some kind is always recommended.

1 Like