How to Properly Check If Non-Optional Return Value Is Valid

How to properly check if non-Optional return value is valid?

It actually is Optional, the compiler just isn't showing it to you.

In Apple's documentation about working with Objective-C objects, it says that all objects imported from Objective-C APIs are actually implicitly unwrapped optionals (like we would manually declare with !):

In some cases, you might be absolutely certain that an Objective-C
method or property never returns a nil object reference. To make
objects in this special scenario more convenient to work with, Swift
imports object types as implicitly unwrapped optionals. Implicitly
unwrapped optional types include all of the safety features of
optional types. In addition, you can access the value directly without
checking for nil or unwrapping it yourself. [source]

Unfortunately, the compiler/syntax checker doesn't treat them as such. Therefore, the correct way of checking would be to declare image as the type that the NSImage initializer is actually returning, an implicitly unwrapped optional NSImage:

let image: NSImage! = NSImage(named: "CorrectIconName")
if image {
// do something
}

Alternate method (via @vacawama):

if let image = NSImage(named: "CorrectIconName") as NSImage! {
// do something
}

What's wrong with comparing non-optional bool in a single if structure in swift

A bit of history...

In Swift 1.0, it was possible to check if an optional variable optVar contained a value by just checking:

if optVar {
println("optVar has a value")
} else {
println("optVar is nil")
}

In The Swift Programming Language, the update for Swift 1.1 (dated 2014-10-16) stated:

Optionals no longer implicitly evaluate to true when they have a value and false when they do not, to avoid confusion when working with optional Bool values. Instead, make an explicit check against nil with the == or != operators to find out if an optional contains a value.

So, the nonsensical error message that you are getting was put there because the Swift compiler is interpreting your:

if a {
}

to mean:

if a != nil {
}

and it is encouraging you to test against nil to determine if the Optional a has a value.

Perhaps the Swift authors will change it in the future, but for now you will have to explicitly unwrap a:

if a! {
}

or check against true:

if a == true {
}

or (to be completely safe):

if a ?? false {
print("this will not crash if a is nil")
}

Why is my carefully designed to be not-optional return value being treated like an optional?

You are creating your new view controller instance with

let theVC = SelectDateRangeViewController()

Since you don't get the instance from the storyboard, none of the outlets are bound; they will be nil. As your outlets are declared as implicitly unwrapped optionals, you get a crash when you refer to them.

You could instantiate the new view controller from your storyboard but it would probably be simpler to use a segue either directly from your button or by using performSegue in your @IBAction

How to return when an optional is empty?

You could use orElse(null):

String o = getOptional().orElse(null);
if (o == null) {
return;
}

Determine if Any.Type is Optional

Assuming that what you are trying to do is something like this:

let anyType: Any.Type = Optional<String>.self
anyType is Optional<Any>.Type // false

Sadly swift currently (as of Swift 2) does not support covariance nor contravariance and type checks directly against Optional.Type cannot be done:

// Argument for generic parameter 'Wrapped' could not be inferred
anyType is Optional.Type // Causes error

An alternative is to make Optional extend an specific protocol, and check for that type:

protocol OptionalProtocol {}

extension Optional : OptionalProtocol {}

let anyType: Any.Type = Optional<String>.self
anyType is OptionalProtocol.Type // true

How to avoid returning an optional after throwing an exception?

You can use Swift assert(_:_file:line:) function as follows

assert(some condition, "Message to display if condition is false (optional)" )

If the condition is verified the app will continue running, otherwise it will terminate



Related Topics



Leave a reply



Submit