How to Use Nil Coalescing in Swift

Nil coalescing lets you replace nil with a default value using the ?? operator.

What you’ll build or solve

You’ll learn how to turn optional values into usable defaults with ??. Done means you can remove unnecessary if let blocks and safely handle nil in expressions and assignments.

When this approach works best

Nil coalescing works best when:

  • You want fallback text in a UI label.
  • You need a default number for calculations.
  • You convert optional API data into guaranteed values.
  • You want layered fallback logic across multiple optionals.

This is a bad idea if missing data should stop execution. In that case, use guard let or if let instead of silently providing a default.

Prerequisites

  • Xcode installed
  • Basic Swift syntax
  • Understanding of optionals (String?, Int?)

Step-by-step instructions

Step 1: Use ?? to provide a default value

Nil coalescing uses this syntax:

optionalValue ?? defaultValue

If optionalValue contains a value, Swift returns it.

If it is nil, Swift returns defaultValue.

Example

var username: String? = nil
let displayName = username ?? "Guest"

If username is "Alex", displayName becomes "Alex".

If username is nil, displayName becomes "Guest".


Getting a non-optional result

The result type matches the default value. This often gives you a non-optional result:

var score: Int? = nil
let finalScore: Int = score ?? 0

finalScore is Int, not Int?.


What to look for

  • The left side must be optional.
  • The default must match the wrapped type.
  • The result is non-optional if the default is non-optional.

Works well after optional chaining:

let email = user.profile?.email ?? "No email"

Can be used inside expressions:

let finalPrice = price - (discount ?? 0)

Use ?? only when a fallback value makes logical sense.


Step 2: Chain multiple ?? for layered fallbacks

You can stack nil coalescing operators.

var nickname: String? = nil
var username: String? = nil

let displayName = nickname ?? username ?? "Guest"

Swift evaluates from left to right and returns the first non-nil value.

Order matters:

  1. Check nickname
  2. If nil, check username
  3. If both are nil, use "Guest"

This works well when you have multiple possible sources for the same value.


Examples you can copy

Example 1: Safe UI label

var title: String? = nil
let navigationTitle = title ?? "Home"

The label always shows readable text.


Example 2: Handling API numbers

struct APIResponse {
    var likes: Int?
}

let response = APIResponse(likes: nil)

let likesCount = response.likes ?? 0
print("Likes: \(likesCount)")

You avoid optional math and keep the UI stable.


Example 3: Fallback after optional chaining

struct Profile {
    var email: String?
}

struct User {
    var profile: Profile?
}

let user = User(profile: nil)

let email = user.profile?.email ?? "No email provided"
print(email)

If any part of the chain is nil, the default is used.


Common mistakes and how to fix them

Mistake 1: Using mismatched types

What you might do:

var age: Int? = nil
let finalAge = age ?? "Unknown"

Why it breaks:

age is Int?, but "Unknown" is a String.

Correct approach:

let finalAge = age ?? 0

Or change your model so the types align.


Mistake 2: Hiding required validation

What you might do:

var password: String? = nil
let safePassword = password ?? ""

Why it breaks:

An empty string may bypass validation logic. Missing data should not always be replaced silently.

Correct approach:

guard let password = password else {
    print("Password required")
    return
}

Use ?? only when a fallback value is logically correct.


Troubleshooting

If you see “Value of optional type must be unwrapped,” check that you used ?? or safe binding.

If your result is still optional, confirm the default value is not optional.

If the fallback never runs, verify the original value is actually nil.

If chained ?? operators behave unexpectedly, check the evaluation order from left to right.


Quick recap

  • Use ?? to replace nil with a default value.
  • The left side must be optional.
  • The default must match the wrapped type.
  • The result becomes non-optional if the default is non-optional.
  • You can chain multiple ?? operators.
  • Use guard let instead when missing data stops execution.