Swift
File Handling
Programming Tutorials
iOS Development
Code Examples

How to check if a file exists in the Documents directory in Swift?

Master System Design with Codemia

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

Introduction

On Apple platforms, the Documents directory is the usual place for app files that should persist across launches and participate in normal backup behavior. Checking whether a file exists there is straightforward with FileManager, but it is worth doing it with sandbox-aware URLs rather than manual path strings.

Get the Documents Directory Safely

Every app runs in its own sandbox, so you should ask the system for the Documents directory instead of assuming a fixed path. FileManager.default.urls(for:in:) is the standard API for that.

swift
1import Foundation
2
3let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
4print(documentsURL.path)

That returns a URL pointing at the app's Documents directory. Once you have it, build the target file URL by appending a path component.

Check Whether the File Exists

The normal existence check is to append the filename and ask FileManager whether something exists at that path.

swift
1import Foundation
2
3func fileExistsInDocuments(named fileName: String) -> Bool {
4    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
5    let fileURL = documentsURL.appendingPathComponent(fileName)
6    return FileManager.default.fileExists(atPath: fileURL.path)
7}
8
9print(fileExistsInDocuments(named: "notes.json"))

This is the simplest correct answer for most apps.

A Complete Example with Write and Read

It helps to see the check in context. This example creates a file in Documents, then verifies its existence and reads it back:

swift
1import Foundation
2
3let fileManager = FileManager.default
4let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
5let fileURL = documentsURL.appendingPathComponent("example.txt")
6
7let text = "Hello, Documents directory"
8try text.write(to: fileURL, atomically: true, encoding: .utf8)
9
10if fileManager.fileExists(atPath: fileURL.path) {
11    let contents = try String(contentsOf: fileURL, encoding: .utf8)
12    print(contents)
13}

Using URL values throughout keeps the code aligned with modern Foundation APIs and avoids the fragility of hand-built path strings.

Distinguish "Exists" from "Is a File"

fileExists(atPath:) tells you whether something exists at that path. It does not automatically guarantee that the item is a regular file rather than a directory. If that distinction matters, use the overload with the isDirectory output parameter.

swift
1import Foundation
2
3func regularFileExistsInDocuments(named fileName: String) -> Bool {
4    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
5    let fileURL = documentsURL.appendingPathComponent(fileName)
6
7    var isDirectory: ObjCBool = false
8    let exists = FileManager.default.fileExists(atPath: fileURL.path, isDirectory: &isDirectory)
9    return exists && !isDirectory.boolValue
10}

That matters if names are user-controlled or if your code can create both files and folders in the same area.

Prefer URLs Over Manual Path Concatenation

It is tempting to write something like documentsPath + "/notes.json", but appendingPathComponent is safer and clearer:

swift
let fileURL = documentsURL.appendingPathComponent("notes.json")

This avoids bugs caused by missing or duplicated slashes and keeps the representation strongly tied to file URLs instead of opaque strings.

Choosing the Right Directory

Sometimes the more important design question is whether the Documents directory is the right location at all. Documents is appropriate for user data that should persist and usually be backed up. Re-creatable files, downloads, and temporary data may belong in Caches or a temporary directory instead.

The file existence check itself is similar in those locations, but placing the file in the right directory affects backup behavior, cleanup policy, and app review expectations.

Common Pitfalls

The most common mistake is hardcoding a path instead of resolving the sandbox directory through FileManager. Another is building the file path by concatenating strings, which is more fragile than appendingPathComponent. Developers also sometimes treat fileExists(atPath:) as proof that the item is a normal file even though it could be a directory. A final issue is storing cache-like data in Documents and then checking for it there as if that location were automatically appropriate.

Summary

  • Use FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) to locate Documents.
  • Build file paths with appendingPathComponent.
  • Use fileExists(atPath:) for a basic existence check.
  • Use the isDirectory overload when file vs directory matters.
  • Prefer URL-based file handling over manual path-string construction.

Course illustration
Course illustration

All Rights Reserved.