Can you safely unwrap nested optionals in swift in one line?

Viewed 1145

I'm currently using four lines to unwrap the title from mapViewDidSelectMKAnnotationView.

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    if let title = view.annotation?.title {
        if let title = title {
            // do something with title
        }
    }
}

Can I do this without having to unwrap things twice? Something like:

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    if let title = view.annotation?.title? {
        // do something with title
    }
}

This answer seems to get really close to the question but doesn't address the case of the deepest property being an optional. It seems like a pretty trivial thing and I'm certain there must be a way but I can't work out the syntax for the life of me.

2 Answers

You could do it like so:

if let title = view.annotation?.title as? String {

}

view.annotation?.title is a double optional string: String?? since both the property annotation of an MKAnnotationView, and its own property title, are optional.


You could also use the guard statement like so:

guard let title = view.annotation?.title as? String else {
    return 
}
//use title in the rest of the scope

you could also use a switch statement :

switch title {
case .some(.some(let t)):
    //use the title here
    print(t)
default:
    break 
}

To unwrap to a single optional string, you can use

let title = (view.annotation.title ?? nil)

You can then use null coalescing to fall back to a default string:

let title = (view.annotation.title ?? nil) ?? "fallback string"

Related