Swift
Deprecation
Programming
Characters
String Handling

warning 'characters' is deprecated Please use String or Substring directly

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The Swift warning about characters being deprecated means the language no longer wants you to access a separate characters view on String. Modern Swift treats String itself as a collection of Character values, so most old code can be simplified rather than replaced with a new special API.

In practice, the fix is usually mechanical: remove .characters and operate directly on the String or Substring. The only part worth thinking about is whether your code should keep a slice as Substring or convert it back to String.

Why characters Went Away

Older Swift versions had separate views such as myString.characters. That design made string handling noisier and harder to teach. Since Swift 4, strings themselves conform to collection protocols in a way that lets you iterate over characters directly.

So instead of writing this old style:

swift
1let text = "hello"
2print(text.characters.count)
3for ch in text.characters {
4    print(ch)
5}

You now write:

swift
1let text = "hello"
2print(text.count)
3for ch in text {
4    print(ch)
5}

That is the main meaning of the deprecation warning.

Common Replacements

A few old patterns show up repeatedly in legacy code.

Counting characters:

swift
let word = "naive"
print(word.count)

Checking emptiness:

swift
let input = ""
print(input.isEmpty)

Iterating over characters:

swift
for character in "Swift" {
    print(character)
}

Converting a character sequence back into a string is also straightforward:

swift
let letters = [Character]("code")
let text = String(letters)
print(text)

All of these replace old .characters-based code with direct String usage.

Substring Is the Other Half of the Change

When you slice a string in modern Swift, the result is usually a Substring, not a new String. That is good for performance because it avoids copying immediately.

swift
1let phrase = "hello world"
2let index = phrase.firstIndex(of: " ")!
3let firstWord = phrase[..<index]
4
5print(firstWord)
6print(type(of: firstWord))

If another API requires a String, convert explicitly:

swift
let firstWordString = String(firstWord)
print(firstWordString)

That is why the warning mentions String or Substring directly. The language wants you to use the real types involved rather than an older compatibility layer.

Character Handling in Swift Is Unicode-Aware

One reason Swift string APIs can feel different from some other languages is that a Character is not just one byte. Swift characters are Unicode-aware and can represent extended grapheme clusters.

That means operations such as counting or indexing characters are based on user-visible characters, not raw UTF-8 bytes. This is a good thing, but it also means you should avoid assumptions like "the fifth byte is the fifth character."

The deprecation of .characters did not remove Character as a concept. It just removed the extra collection wrapper around it.

Updating Legacy Code Safely

For most codebases, migration is a simple search-and-replace followed by a type check.

Typical rewrites:

  • 'str.characters.count becomes str.count'
  • 'for c in str.characters becomes for c in str'
  • 'String(str.characters.prefix(3)) becomes String(str.prefix(3))'

Example:

swift
let username = "markqian"
let prefix = String(username.prefix(4))
print(prefix)

After the mechanical cleanup, review any APIs that return slices. If a value needs to outlive the original string or be stored independently, convert the Substring to String explicitly.

Common Pitfalls

The main mistake is trying to find a direct replacement property for .characters instead of noticing that String already does the job. Another is forgetting that slices return Substring, which can cause type mismatches when code expects String. Developers also still make byte-based assumptions about character counts, which leads to bugs with emoji and accented characters. The warning is easy to silence, but the real goal is to update your mental model of how Swift strings work.

Summary

  • The .characters view was deprecated because String itself is a collection of Character values.
  • Most old code can be fixed by removing .characters directly.
  • Use count, iteration, and collection methods on String itself.
  • String slices are usually Substring, and you can convert them with String(...) when needed.
  • Remember that Swift string operations are Unicode-aware, not byte-based.

Course illustration
Course illustration

All Rights Reserved.