Does using the keyword guard inside a function automatically make a function's parameter optional in swift?

362 Views Asked by At

I'm fairly new to programming and I'm reading the Start Developing iOS Apps (Swift) programming guide. I understand that optionals have a question mark suffix which means the value could be nil or some other value. Apple's guide is walking us through how to use UIImagePickerController and it's delegate. Apple uses the delegate method imagePickerControllerdidFinishPickingMediaWithInfo(_:) which has a dictionary as a parameter.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
            fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
        }
    }

Apple's UIImagePickerControllerDelegate documentation doesn't list this parameter as optional nor is the UIImagePickerController instance we created for this tutorial an optional however the tutorial states the following:

"This code accesses the original, unedited image from the info dictionary. It safely unwraps the optional returned by the dictionary and casts it as a UIImage object. The expectation is that the unwrapping and casting operations will never fail. If they do, it represents either a bug in your app that needs to be fixed at design time."

Does this mean that by using the guard keyword, it automatically turns the variable into an optional?

3

There are 3 best solutions below

0
On BEST ANSWER

No. The optional value arises from the attempt to retrieve a value from a dictionary. Although the info argument is a non-optional dictionary of type [String: Any], the subscript reference info[UIImagePickerControllerOriginalImage] returns an optional value of type Any?.

From The Swift Programming Language (Swift 3.0.1), "Accessing and Modifying a Dictionary":

Because it is possible to request a key for which no value exists, a dictionary’s subscript returns an optional value of the dictionary’s value type. If the dictionary contains a value for the requested key, the subscript returns an optional value containing the existing value for that key. Otherwise, the subscript returns nil:

if let airportName = airports["DUB"] {
    print("The name of the airport is \(airportName).")
} else {
    print("That airport is not in the airports dictionary.")
}
// Prints "The name of the airport is Dublin Airport."
0
On

As per Apple Documentation

A guard statement is used to transfer program control out of a scope if one or more conditions aren’t met.

and

The value of any condition in a guard statement must be of type Bool or a type bridged to Bool. The condition can also be an optional binding declaration.

So guard guarantees that the variable always contain a value or the control will be transfer to out of the scope.

It does not make any other variable optional.

0
On

In a word, no.

The guard statement asserts that some boolean expression is true, or it forces an exit of the current scope. It is commonly used with let to unwrap an optional and continue if the optional contains a value or exit if it is nil but it doesn't have to do that. You can also use code like this:

guard x == 3 else {
  return
}

Or any expression that evaluates to a boolean (true/false) value.