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("") // true
Now, add import Foundation
:
import Foundation
"".contains("") // false
"string".contains("") // false
The 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,
contains
refers to Swift’s native implementation, which returnstrue
if the searched substring is empty. - With Foundation,
contains
resolves toNSString
’s implementation, which returnsfalse
for 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.
If you enjoyed this article, please feel free to follow me on my social media: