How do I check if a string contains another string in Objective-C?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Checking whether one NSString contains another is a very common Objective-C task, and the correct approach depends mostly on deployment target and matching rules. For modern code the shortest answer is often containsString:, but rangeOfString: remains the more flexible tool and is still the best fallback for older platforms.
Use rangeOfString: As The Compatible Baseline
The classic Objective-C solution is rangeOfString:. It searches for the first occurrence of a substring and returns an NSRange. If the substring is missing, the range location is NSNotFound.
This works on older iOS and macOS targets, which is why it is still the safest general answer in Objective-C codebases that care about compatibility.
Use containsString: For Simpler Modern Code
If your deployment target includes iOS 8 or later, containsString: is more direct:
This returns a BOOL, which is exactly what you want when the only question is containment. It is more readable than checking NSNotFound, but it does not replace rangeOfString: when you need more control.
Handle Case-Insensitive Searches Explicitly
Both of the basic examples above are case-sensitive. If the match should ignore case, use rangeOfString:options:.
This is usually better than lowercasing both strings manually because it keeps the search behavior in one place and works naturally with the NSString APIs.
If locale rules matter, use the longer variant with an explicit locale. That is more advanced, but it matters when the application handles natural-language text rather than simple identifiers.
Search Only Part Of The String When Needed
Sometimes the requirement is not "does the whole string contain this substring?" but "does this substring appear after a certain point?" or "inside a particular range only?" In that case, use the range-limited search API.
This is one reason rangeOfString: remains the more powerful building block even in modern code.
Know What Kind Of Match You Really Need
A containment check is different from checking prefixes, suffixes, or exact equality. If the real question is "does the string start with" or "does the string end with", use hasPrefix: or hasSuffix: instead of a general substring search.
That makes the code easier to read and communicates the real intent immediately.
Common Pitfalls
- Using
containsString:on projects that still target older iOS versions where it is unavailable. - Forgetting that default substring searches are case-sensitive.
- Lowercasing both strings manually when
rangeOfString:options:would express the intent more clearly. - Treating a containment check as equivalent to a prefix or suffix check.
- Forgetting to handle
nilvalues before sending messages to the strings involved.
Summary
- '
rangeOfString:is the classic Objective-C way to test substring containment and works across older targets.' - '
containsString:is cleaner when you only need aBOOLand your deployment target supports it.' - Use
NSCaseInsensitiveSearchwhen matching should ignore case. - Reach for prefix, suffix, or range-limited APIs when those better match the real requirement.

