Checking the value of an Optional Bool

var enabled: Bool? = true

if enabled == true {
    print("when is defined and true at the same moment")
}

if enabled == false {
    print("when is defined and false at the same moment")
}

if let enabled = enabled, enabled == true {
    print("when is defined and true at the same moment")
}

if let enabled = enabled, enabled == false {
    print("when is defined and false at the same moment")
}

if let enabled = enabled, enabled {
    print("when is defined and true at the same moment")
}

if let enabled = enabled, !enabled {
    print("when is defined and false at the same moment")
}

if enabled ?? false {
    print("when is defined and true at the same moment")
}

if enabled == .some(true) {
    print("when is defined and true at the same moment")
}

if enabled == (true) {
    print("when is defined and true at the same moment")
}

if case .some(true) = enabled {
    print("when is defined and true at the same moment")
}

if enabled == .some(false) {
    print("when is defined and false at the same moment")
}

if enabled == (false) {
    print("when is defined and false at the same moment")
}

if enabled == .none {
    print("when is not defined")
}

if enabled == nil {
    print("when is not defined")
}

Optional binding

Swift 3 & 4

var booleanValue : Bool? = false
if let booleanValue = booleanValue, booleanValue {
    // Executes when booleanValue is not nil and true
    // A new constant "booleanValue: Bool" is defined and set
    print("bound booleanValue: '\(booleanValue)'")
}

Swift 2.2

var booleanValue : Bool? = false
if let booleanValue = booleanValue where booleanValue {
    // Executes when booleanValue is not nil and true
    // A new constant "booleanValue: Bool" is defined and set
    print("bound booleanValue: '\(booleanValue)'")
}

The code let booleanValue = booleanValue returns false if booleanValue is nil and the if block does not execute. If booleanValue is not nil, this code defines a new variable named booleanValue of type Bool (instead of an optional, Bool?).

The Swift 3 & 4 code booleanValue (and Swift 2.2 code where booleanValue) evaluates the new booleanValue: Bool variable. If it is true, the if block executes with the newly defined booleanValue: Bool variable in scope (allowing the option to reference the bound value again within the if block).

Note: It's a Swift convention to name the bound constant/variable the same as the optional constant/variable such as let booleanValue = booleanValue. This technique is called variable shadowing. You could break from convention and use something like let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue. I point this out to help understand what's happening. I recommend using variable shadowing.

 

Other Approaches

Nil coalescing

Nil coalescing is clear for this specific case

var booleanValue : Bool? = false
if booleanValue ?? false {
    // executes when booleanValue is true
    print("optional booleanValue: '\(booleanValue)'")
}

Checking for false is not as clear

var booleanValue : Bool? = false
if !(booleanValue ?? false) {
    // executes when booleanValue is false
    print("optional booleanValue: '\(booleanValue)'")
}

Note: if !booleanValue ?? false does not compile.

 

Force unwrapping optional (avoid)

Force unwrapping increases the chance that someone will make a change in the future that compiles but crashes at runtime. Therefore, I would avoid something like this:

var booleanValue : Bool? = false
if booleanValue != nil && booleanValue! {
    // executes when booleanValue is true
    print("optional booleanValue: '\(booleanValue)'")
}

 

A General Approach

Though this stack overflow question asks specifically how to check if a Bool? is true within an if statement, it's helpful to identify a general approach whether checking for true, false or combining the unwrapped value with other expressions.

As the expression gets more complicated, I find the optional binding approach more flexible and easier to understand than other approaches. Note that optional binding works with any optional type (Int?, String?, etc.).


With optional booleans it's needed to make the check explicit:

if boolean == true {
    ...
}

Otherwise you can unwrap the optional:

if boolean! {
    ...
}

But that generates a runtime exception if boolean is nil - to prevent that:

if boolean != nil && boolean! {
    ...
}

Before beta 5 it was possible, but it has been changed as reported in the release notes:

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.

Addendum: as suggested by @MartinR, a more compact variation to the 3rd option is using the coalescing operator:

if boolean ?? false {
    // this code runs only if boolean == true
}

which means: if boolean is not nil, the expression evaluates to the boolean value (i.e. using the unwrapped boolean value), otherwise the expression evaluates to false