Case insensitive string comparison in Swift

String comparison is a fundamental aspect of many programming tasks, from sorting and searching to data validation. The simplest method to compare two strings ignoring case we might think of is converting them to a common case and using ==. However, this approach has significant limitations.

Languages and locales have specific rules for case mappings, making simple case conversion unreliable. Let's look at an example in German.

let string1 = "Fußball"
let string2 = "FUSSBALL"

// Prints `false`
print(string1.lowercased() == string2.lowercased())

The lowercase of ß in German is not equivalent to ss, leading to a false negative in comparison.

Also note that using lowercased() creates new string instances, which can be a performance bottleneck. And simple case conversion does not respect locale-specific sorting rules, leading to lists that might appear incorrectly ordered to users.

Fortunately, the Foundation framework offers more nuanced methods for string comparison.

For non-user-facing comparisons we can use the compare(_:options:) method or any of its overloads. It allows us to request specific comparison behaviors like case-insensitive, diacritic-insensitive, or numeric comparison.

let result = string1.compare(string2, options: [.caseInsensitive, .diacriticInsensitive])
if result == .orderedSame {
    print("The strings are considered equal.")
}

For user-facing, locale-aware comparison, we should use compare(_:options:range:locale:) or localizedStandardCompare(_:).

localizedStandardCompare(_:) can come in handy when sorting strings that will be displayed to users, like filenames, titles, or any list that requires natural sorting order. It will compare strings in a way that aligns with human expectations, even considering numeric values embedded in strings.

let filenames = ["File10.txt", "file2.txt", "FILE1.txt"]
let sortedFilenames = filenames.sorted(
    by: { $0.localizedStandardCompare($1) == .orderedAscending }
)

// Prints `["FILE1.txt", "file2.txt", "File10.txt"]`
print(sortedFilenames)

By selecting the most suitable method for our specific situation, we can ensure that our string comparisons are not only correct but also efficient and considerate of the user's cultural context. This careful approach can greatly improve the user experience and the overall reliability of our applications.

Integrating SwiftUI into UIKit Apps by Natalia Panferova book coverIntegrating SwiftUI into UIKit Apps by Natalia Panferova book cover

Check out our book!

Integrating SwiftUI into UIKit Apps

Integrating SwiftUI intoUIKit Apps

UPDATED FOR iOS 17!

A detailed guide on gradually adopting SwiftUI in UIKit projects.

  • Discover various ways to add SwiftUI views to existing UIKit projects
  • Use Xcode previews when designing and building UI
  • Update your UIKit apps with new features such as Swift Charts and Lock Screen widgets
  • Migrate larger parts of your apps to SwiftUI while reusing views and controllers built in UIKit