Working with Files in Swift: From Opening to Encryption

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Swift is Not Just About UI, But Also About Files

\n\n

When developers start learning Swift, they most often write applications with interfaces, animations, and network requests. But sooner or later a task arises: save data on the device, read a config, parse a JSON file, or simply copy a document. And many get lost here. But it's a shame — working with files in Swift is so elegant and well-thought-out that you don't want to go back to other languages after it.

\n\n

In this article, we will cover interacting with the file system in Swift from simple to complex. You will learn how to create, read, write, and delete files, work with directories, handle errors, and even encrypt data. Let's go!

\n\n

Basics: FileManager and FileHandle

\n\n

The heart of the file system in Swift is the FileManager class. It is a "manager" that knows everything about folders and files on the device. It allows you to check existence, move, copy, and delete objects. To work with file contents (reading and writing), FileHandle or higher-level methods of Data, String, and Codable are used.

\n\n

Where to Store Files? Paths and Directories

\n\n

Before writing code, you need to understand where we have permission to save data. In iOS and macOS, there are strict rules: an application can only write to its sandbox. The most popular directories are:

\n\n
    \n
  • Documents — for user data that should be preserved during backups.
  • \n
  • Library/Caches — for temporary files that the system can delete.
  • \n
  • tmp — for disposable files, deleted upon reboot.
  • \n
\n\n

Getting the path to the desired folder is very simple:

\n\n
import Foundation\n\nlet fileManager = FileManager.default\nlet documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!\nprint("Documents: \\(documentsURL.path)")\n\nlet cachesURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!\nprint("Caches: \\(cachesURL.path)")
\n\n

Creating and Deleting Files in Swift

\n\n

Let's start with the most basic — create an empty file in the Documents directory:

\n\n
let fileURL = documentsURL.appendingPathComponent("myFile.txt")\n\n// Create the file if it doesn't exist\nif !fileManager.fileExists(atPath: fileURL.path) {\n    fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil)\n    print("File created!")\n}
\n\n

Note: createFile(atPath:contents:attributes:) returns a Bool that tells you whether the file was created successfully. Always check the result — this will save you from unexpected errors.

\n\n

Deleting a file is done in one line:

\n\n
do {\n    try fileManager.removeItem(at: fileURL)\n    print("File deleted")\n} catch {\n    print("Deletion error: \\(error.localizedDescription)")\n}
\n\n

Here we use try and a do-catch block — the standard approach for error handling in Swift. Never call removeItem without checking, otherwise the application will crash.

\n\n

Reading and Writing Text Files

\n\n

The most common scenario is working with text data. Swift offers convenient methods for reading a file in Swift and writing via strings:

\n\n
// Writing text\nlet text = "Hello, world! Hello, Swift!"\ndo {\n    try text.write(to: fileURL, atomically: true, encoding: .utf8)\n    print("Text written")\n} catch {\n    print("Write error: \\(error)")\n}\n\n// Reading text\ndo {\n    let savedText = try String(contentsOf: fileURL, encoding: .utf8)\n    print("Read: \\(savedText)")\n} catch {\n    print("Read error: \\(error)")\n}
\n\n

The atomically: true flag guarantees that the write will be atomic — the data is first written

Blogs

Book Recommendations