Swift
Programming
File Handling
Filename Split
Code Tutorial

How to split filename from file extension in Swift?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

In Swift, the safest way to split a filename from its extension is to use path-aware APIs rather than manual string splitting. Foundation already understands file paths, multiple dots, and common edge cases better than a raw split(separator: ".") call.

Use URL path utilities

If you have a path or filename string, turn it into a file URL and ask Foundation for the pieces:

swift
1import Foundation
2
3let path = "/Users/markqian/Documents/report.final.pdf"
4let url = URL(fileURLWithPath: path)
5
6let filenameWithoutExtension = url.deletingPathExtension().lastPathComponent
7let fileExtension = url.pathExtension
8
9print(filenameWithoutExtension) // report.final
10print(fileExtension)            // pdf

This is usually the best solution because it is path-aware. It does not just split on the first or last dot blindly; it uses Foundation's path rules.

If you only have a bare filename rather than a full path, the same approach still works:

swift
let url = URL(fileURLWithPath: "archive.tar.gz")
print(url.deletingPathExtension().lastPathComponent) // archive.tar
print(url.pathExtension)                             // gz

Notice that only the last extension is removed. That is often exactly what you want.

NSString path helpers also work

Older Swift code often uses NSString path methods, and they are still valid:

swift
1import Foundation
2
3let filename = "photo.backup.jpg" as NSString
4
5let base = filename.deletingPathExtension
6let ext = filename.pathExtension
7
8print(base) // photo.backup
9print(ext)  // jpg

This is especially common in Swift 3 and early Foundation-heavy codebases. Under the hood, it is still relying on path semantics rather than naive string splitting, which is the important part.

Why manual splitting is often wrong

A tempting solution looks like this:

swift
let name = "report.final.pdf"
let parts = name.split(separator: ".")

The problem is that filenames are messier than they seem:

  • 'report.final.pdf has more than one dot'
  • '.gitignore starts with a dot but is not always treated like a normal extension case'
  • 'archive.tar.gz may conceptually have more than one suffix'
  • full paths can contain dots in directory names too

If you manually split strings, you end up reimplementing path logic badly.

Handle dotfiles and no-extension cases carefully

Two cases deserve explicit attention.

No extension:

swift
let url = URL(fileURLWithPath: "README")
print(url.deletingPathExtension().lastPathComponent) // README
print(url.pathExtension)                             // empty string

Dotfile:

swift
let url = URL(fileURLWithPath: ".gitignore")
print(url.deletingPathExtension().lastPathComponent)
print(url.pathExtension)

The exact result for dotfiles can surprise people because a leading dot is part of Unix-style naming conventions, not just an extension separator. That is one more reason to trust Foundation path APIs instead of hand-written parsing.

If you need every extension segment

Sometimes you do want more control, for example to distinguish archive.tar.gz into base name archive and compound extension tar.gz. In that case, Foundation's default single-extension behavior may not be enough, so you can layer custom logic on top:

swift
1import Foundation
2
3let filename = "archive.tar.gz"
4let components = filename.split(separator: ".")
5
6if components.count >= 3 {
7    let base = components.dropLast(2).joined(separator: ".")
8    let compoundExtension = components.suffix(2).joined(separator: ".")
9    print(base)               // archive
10    print(compoundExtension)  // tar.gz
11}

This is one of the few cases where manual splitting is reasonable, because you are explicitly implementing a special rule rather than pretending it is the general case.

Common Pitfalls

The biggest mistake is using plain string splitting for every filename problem. That breaks easily on multi-dot names and full paths.

Another common issue is forgetting that pathExtension returns only the last extension segment. That is correct behavior, but it may not match your business rule for files such as archive.tar.gz.

People also test only simple filenames and forget dotfiles, files without extensions, or paths that include directories.

Finally, do not confuse a path with a display name. If you only want the last file component, call lastPathComponent rather than trying to strip directories manually.

Summary

  • Prefer URL(fileURLWithPath:), deletingPathExtension(), and pathExtension.
  • 'NSString path helpers are also valid, especially in older Swift codebases.'
  • Avoid manual split(separator: ".") for general filename parsing.
  • Remember that Foundation removes only the last extension by default.
  • Add custom logic only when you explicitly need compound extensions such as tar.gz.

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.