Greetings, traveler!
Swift is often described as a modern language with its own standard library, while Foundation comes from the Objective-C era and provides a wide set of APIs for working with strings, collections, dates, and more. What’s less obvious is that importing Foundation can actually change the behavior of methods you might think are purely part of Swift.
A recent example illustrates this well.
The String.contains Surprise
Consider the following code, without importing Foundation:
"".contains("") // true
"string".contains("") // trueNow, add import Foundation:
import Foundation
"".contains("") // false
"string".contains("") // falseThe contains suddenly behaves differently for empty substrings.
Why This Happens
String in Swift is bridged to Objective-C’s NSString when you import Foundation. This means that many NSString instance methods become available directly on String. If NSString has a method with the same name and compatible signature as one in Swift’s standard library, the Objective-C method may take precedence in overload resolution.
In this case:
- Without Foundation,
containsrefers to Swift’s native implementation, which returnstrueif the searched substring is empty. - With Foundation,
containsresolves toNSString’s implementation, which returnsfalsefor an empty substring.
Practical Impact
In most real-world iOS projects, you have Foundation imported indirectly through UIKit, SwiftUI, or AppKit, so the Foundation behavior is what you’ll encounter. The “pure Swift” implementation is mostly visible in isolated Swift-only modules.
Takeaway
When working in Swift, especially in cross-platform or Swift-only contexts, be aware that importing Foundation can alter method resolution for bridged types. If a method starts behaving differently than you expect, check whether you’re calling the Swift or the Objective-C implementation.
