How to Use the is Operator in Swift

Use the is operator in Swift when you need to check whether a value matches a specific type at runtime without actually converting it. This is especially useful with inheritance, protocol-based collections, and mixed arrays.

What you’ll build or solve

You’ll learn how to use the is operator in Swift for runtime checks, branching logic, and collection filtering. You’ll also know when as? is the better next step.

When this approach works best

This approach is the right choice when the type only needs to be checked before deciding what logic to run.

Common real-world scenarios include:

  • UIView hierarchies
  • Media item lists
  • Mixed arrays
  • Protocol-based dispatch
  • Analytics event processing

This is a bad idea when you immediately need subtype properties, where direct casting is clearer.

Prerequisites

You only need:

  • Basic Swift classes
  • Inheritance
  • Familiarity with conditionals

Step-by-step instructions

Step 1: Check a subtype in inheritance

The most common use is class hierarchies.

if view is UIButton {
    print("This is a button")
}

This only checks the runtime type.

It does not convert the value.

Step 2: Use is in mixed arrays

This is useful for heterogeneous collections.

let items: [Any] = ["Swift", 42, true]

for item in items {
    if item is String {
        print("Text item found")
    }
}

This keeps branching logic safe.

Step 3: Combine is with later casting

A common pattern is check first, then cast.

if view is UIButton, let button = view as? UIButton {
    button.setTitle("Save", for: .normal)
}

This makes intent explicit.

What to look for:

  • is checks type only
  • Great for branching logic
  • Useful in mixed collections
  • Often paired with as?
  • Avoid redundant checks before immediate casting

Examples you can copy

Button check

if view is UIButton

Mixed collection

if item is Int

Protocol check

if object is Codable

Common mistakes and how to fix them

Mistake 1: Using is before immediate casting every time

What the reader might do:

if view is UIButton {
    let button = view as? UIButton
}

Why it breaks: the extra check is redundant.

Corrected approach:

Use just as?.

Mistake 2: Expecting access to subtype members

What the reader might do:

if view is UIButton {
    view.setTitle(...)
}

Why it breaks: the type is only checked, not converted.

Corrected approach:

Use as?.

Mistake 3: Overusing runtime checks in poor design

What the reader might do:

Check types across many unrelated flows.

Why it breaks: the architecture may need protocols or polymorphism.

Corrected approach:

Move behavior into shared interfaces.

Troubleshooting

If subtype properties are needed, switch to as?.

If checks repeat often, improve the type design.

If mixed arrays feel noisy, use enums or protocols.

If the runtime type surprises you, inspect the source hierarchy.

Quick recap

  • is checks type at runtime
  • It does not convert the value
  • Great for branching logic
  • Use as? when subtype access is needed
  • Prefer better type design over repeated checks