How to check what a String starts with prefix or ends with suffix in Swift
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Swift already gives you the two methods you usually want for this job: hasPrefix(_:) and hasSuffix(_:). They are simple, readable, and work correctly with Swift’s Unicode-aware String type. Most of the real nuance comes from case sensitivity and whether you need more advanced matching rules.
Check for a Prefix
Use hasPrefix(_:) when you want to know whether a string begins with a given substring:
This returns a Bool and is case-sensitive by default.
That is usually exactly what you want for things like:
- URL scheme checks
- file extension preparation
- command parsing
- identifier prefixes
Check for a Suffix
Use hasSuffix(_:) for the ending part of the string:
This is a very common pattern for checking file extensions or string markers.
Case-Insensitive Matching
Both methods are case-sensitive, so "Hello".hasPrefix("he") is false. If you need case-insensitive behavior, normalize both sides first:
This is fine for many practical cases, but remember that case conversion can be locale-sensitive in some domains. If exact linguistic behavior matters, use a comparison API with explicit options instead of assuming simple lowercase conversion is always perfect.
When You Need More Control
Sometimes you need rules beyond plain prefix or suffix matching, such as:
- case-insensitive search without creating lowercase copies
- locale-aware comparisons
- ignoring diacritics
- checking only a slice of the string
In those cases, use range(of:options:):
For a suffix-style check, combine .anchored and .backwards:
This gives you more flexibility while still using Swift’s string APIs correctly.
Why Not Use Array-Like Indexing
Developers coming from other languages sometimes try to slice strings using integer indexes. Swift does not support that because strings are Unicode-aware and characters do not have uniform byte widths.
That is exactly why hasPrefix and hasSuffix are so helpful. They let you express intent directly without doing manual index arithmetic.
Practical Examples
Checking a URL scheme:
Checking an image filename:
These examples show why the built-in methods are usually preferable to more complicated manual string code.
Common Pitfalls
The biggest pitfall is forgetting that hasPrefix and hasSuffix are case-sensitive. That leads to a lot of confusing false negatives.
Another common issue is reaching for manual substring indexing when the built-in methods already express the intent clearly and safely.
People also sometimes forget Unicode behavior. Swift strings are not cheap byte arrays, so code patterns copied from other languages may be incorrect or awkward in Swift.
Finally, if the match rules are more complex than plain prefix or suffix logic, move to range(of:options:) instead of forcing everything through lowercase conversion and repeated temporary strings.
Summary
- Use
hasPrefix(_:)to check how a string starts. - Use
hasSuffix(_:)to check how a string ends. - Both methods are case-sensitive by default.
- For case-insensitive or more flexible matching, use
range(of:options:). - Prefer Swift’s string APIs over manual index arithmetic.

