iOS
Swift programming
string manipulation
substrings
iOS development

How to split string into substrings on iOS?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

On iOS, string splitting is usually done with Swift's built-in split API, but the details matter because it returns Substring values rather than full String objects. That design is efficient, but it affects memory behavior, empty-field handling, and how you store the results.

Use Swift split for Simple Delimiters

For a single-character separator such as a comma, pipe, or colon, split(separator:) is the normal starting point.

swift
1let csv = "apple,banana,orange"
2let parts = csv.split(separator: ",")
3
4for part in parts {
5    print(part)
6}

This returns [Substring], not [String]. That is intentional: the pieces reuse the original string storage rather than copying immediately.

Convert to String Only When Needed

If the split pieces are short-lived, keeping them as Substring is fine. If they need to live independently of the source string, convert them.

swift
let words = csv.split(separator: ",").map(String.init)
print(words)

This matters because a Substring keeps the original string alive in memory. If you split a huge source string and hold a few tiny pieces for a long time, the entire original storage can remain retained.

Preserve Empty Fields Explicitly

By default, split omits empty subsequences. That is convenient for casual tokenization but wrong for formats where an empty field has meaning.

swift
1let line = "one,,three,"
2
3let compact = line.split(separator: ",")
4print(compact)
5
6let keepEmpty = line.split(separator: ",", omittingEmptySubsequences: false)
7print(keepEmpty)

If you are parsing CSV-like or delimiter-separated application data, omittingEmptySubsequences: false is often the correct choice.

Limit How Many Times You Split

Sometimes only the first separator matters. For example, configuration lines or key-value pairs may contain the delimiter again later in the value.

swift
let setting = "mode=fast=debug"
let pieces = setting.split(separator: "=", maxSplits: 1)
print(pieces)

That gives you two pieces rather than splitting the entire string.

Use Foundation When the Separator Is More Complex

If the separator is more naturally expressed as a string or character set, Foundation can be more convenient. components(separatedBy:) returns [String] directly.

swift
1import Foundation
2
3let path = "images/icons/home.png"
4let segments = path.components(separatedBy: "/")
5print(segments)

You can also split on multiple delimiter characters:

swift
1import Foundation
2
3let text = "red, green; blue"
4let tokens = text
5    .components(separatedBy: CharacterSet(charactersIn: ",; "))
6    .filter { !$0.isEmpty }
7
8print(tokens)

This is handy when user input is messy and the separators are not a single repeated character.

Swift split vs Foundation components

A practical rule is:

  • use Swift split for simple delimiter logic and efficient temporary parsing
  • use Foundation components(separatedBy:) for string or character-set delimiters

Both are valid. The real difference is convenience and return type rather than correctness.

Avoid Manual Index Arithmetic Unless Necessary

Swift strings are Unicode-correct, which means manual index arithmetic is more complex than in many other languages. For ordinary splitting tasks, built-in APIs are safer and easier to read than walking indices yourself.

Only drop to manual index work when the parsing rule genuinely requires it, such as a custom scanner or a format with escape rules.

Memory and Performance Notes

Substring exists for performance, but that optimization only helps if you use it intentionally. If you need durable values, convert to String and release the source text. If you only need temporary access during parsing, keeping Substring values avoids unnecessary copies.

That is one of the reasons Swift's string APIs look slightly different from older Objective-C or Foundation-first code.

Common Pitfalls

The most common mistake is expecting split to return [String]. It returns [Substring], which is efficient but easy to forget.

Another issue is ignoring empty fields when they are actually meaningful. The default omission behavior can silently drop important data.

Developers also sometimes keep many Substring values for long-term storage and accidentally retain a large original string in memory.

Finally, avoid writing custom index-based splitting code for ordinary delimiters. Swift already provides safe, Unicode-aware APIs that are easier to maintain.

Summary

  • Use split(separator:) for most ordinary string splitting tasks in Swift.
  • Remember that split returns Substring values, not String values.
  • Convert to String when the pieces need independent storage.
  • Use omittingEmptySubsequences: false when empty fields matter.
  • Reach for Foundation components(separatedBy:) when multi-character or character-set delimiters are more natural.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.