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
Substring checks are one of the most common text operations in Objective-C apps, especially for validation, filtering, and parsing user input. The API choice depends on target OS versions, case sensitivity needs, and localization rules. A good implementation favors clarity first, then adds options for case and diacritic handling where needed.
Core Method: rangeOfString:
The classic approach is rangeOfString: on NSString. It returns an NSRange; when the substring is missing, location is NSNotFound.
This method works on old SDKs and is still a strong default when you also care about the match position.
Why this is useful
- You get position and length in one result.
- You can pass options for case or direction.
- It is available in older iOS versions where
containsString:is not.
Simple Boolean Check: containsString:
If you only need yes or no, containsString: reads better.
Use this when match location is irrelevant. The intent is obvious during review, which helps maintenance.
Case Insensitive and Locale Aware Search
Real data often has case differences, accents, and user entered variation. rangeOfString:options:range:locale: gives better control.
This is safer for internationalized apps where strict byte style matching is not enough.
Prefix, Suffix, and Token Checks
Many bugs come from using substring search when a stricter check is required. Use the most specific API for the rule:
- Prefix rule:
hasPrefix: - Suffix rule:
hasSuffix: - Whole token rule: tokenize then compare normalized tokens
A generic substring search would also match malformed inputs that only happen to include the token.
Example Utility Method for Reuse
Centralize search behavior in a helper to keep matching policy consistent across the project.
This pattern avoids duplicated logic and keeps behavior predictable.
Performance Notes
For normal app strings, built in APIs are efficient and should be preferred. Performance work is only needed for extreme workloads, such as scanning large logs repeatedly. In that case:
- Avoid repeated lowercasing of the same large source text.
- Cache normalized forms when practical.
- Benchmark realistic inputs before adding complexity.
Most string search slowdowns are caused by unnecessary repeated work, not by the search API itself.
Common Pitfalls
- Using
containsString:in code that must support older iOS versions without compatibility checks. - Forgetting case or diacritic rules and rejecting valid user input.
- Using substring matching where prefix or exact token matching is required.
- Repeating custom comparison logic across files and creating inconsistent behavior.
- Optimizing early without measuring real string sizes and call frequency.
Summary
- Use
rangeOfString:when you need position data or advanced options. - Use
containsString:for clear boolean checks in modern targets. - Add case and diacritic options for user facing text in multilingual apps.
- Prefer specialized APIs like
hasPrefix:when rules are stricter than substring search. - Centralize matching policy in helpers to keep behavior consistent.

