Brandon A Brandon A - 6 days ago 5
Swift Question

Swift 3: Meaning of parenthesis around unwrapped optional

I have noticed when I code in Swift I routinely get an auto correct from the compiler when I use optionals and I am trying to understand the meaning behind this. When I have a variable that is optional and I try to use without unwrapping it, I often get a

(?)!
autocorrection from Xcode.

In my code I have an optional property that will be the data source collection for my
UITableView
:

var procedures: [Procedure]?


First I will try to use it like so:

enter image description here

The compiler is telling me that I need to use the
?
syntax suffix for my
self.procedures
.

enter image description here

So I click on the little red circle and have it autocorrect for me like so:

enter image description here

But now the compiler is still complaining. About what you ask? Well, it apparently wants
self.procedures?.[indexPath.row]
to be enclosed in parenthesis with the
!
bang operator at the end...

So I click the little red circle again and have it auto correct like so:

enter image description here

Now the compiler is happy, but I am not. Why am I not happy you ask? Because I do not understand what the
()
parenthesis are doing here.

Could someone please explain?

Answer

So as you can see, you are declaring your procedures as an optional

var procedures: [Procedure]?

then you are trying to pass it to a function that will accept Procedure

cell.configureWithProcedure(procedure: Procedure)

Then you are trying to access your procedure with index like this

self.procedures[indexpath.row]

That will result an error because self.procedures is an optional, so you need to unwrap it, then you try to add ?

self.procedures?[indexpath.row]

This will solve the problem, but the result of it won't be a normal Procedure but an Optional Procedure -> Procedure?.
So XCode give you a hint to unwrap it because your configureWithProcedure ask for Procedure not Procedure? in one line that will be writen like this

(self.procedures?[indexPath.row])!

This operation will result unwrapped Procedure, but I don't recommend you to use the ! operator because it's dangerous, so I recommend you to do like this

if let procedure = self.procedures?[indexPath.row] {
    cell.configureWithProcedure(procedure: procedure)
}

EDIT :

in your case you can return an empty cell if procedure isn't exist

extension UITableViewCell {
    dynamic class func emptyCell() -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: nil)
        cell.selectionStyle = UITableViewCellSelectionStyle.None
        return cell
    }
}

and write it like this

if let procedure = self.procedures?[indexPath.row] {
    cell.configureWithProcedure(procedure: procedure)
} else {
    return UITableView.emptyCell()
}

or even better use guard

guard let procedure = self.procedures?[indexPath.row] else {
   return UITableView.emptyCell()
}
cell.configureWithProcedure(procedure: procedure)

Hope my answer can help you!