Welcome to CodableFiles, a simple library that provides an easier way to save, load or delete Codable objects in the Documents directory. It's primarily aimed to save Encodable objects as JSON and load them back as Decodable objects. It's essentially a thin wrapper around the FileManager APIs that Foundation provides.
Every app has a filing cabinet — a quiet corner of the filesystem where structured data needs to live between launches. CodableFiles is the clerk that manages that cabinet. You hand it a Codable object and a name; it encodes, files, and retrieves it without you ever thinking about paths, extensions, or directory creation. The clerk never loses a document, never misfiled one, and never leaves the cabinet door open. You focus on the data; CodableFiles handles the paperwork.
- Protocol-based API (
CodableFilesProviding) for easy mocking and testability. - Unified, simple
do, try, catcherror handling with contextual error messages. - Automatic directory creation and atomic file writes.
- Custom encoder/decoder support for flexible serialization.
- Unit test coverage with both happy-path and error-scenario tests.
Codable object and constants for example purposes.
struct User: Codable {
let name: String
let lastName: String
}
let user = User(name: "First name", lastName: "Last name")
let users = [user]
let fileName = "Users"CodableFiles shared reference.
let codableFiles = CodableFiles.sharedSave object in default directory.
try codableFiles.save(user, withFileName: fileName)Save object with custom encoder.
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
try codableFiles.save(user, encoder: encoder, withFileName: fileName)Load object from default directory.
let user: User = try codableFiles.load(withFileName: fileName)Load array of objects from default directory.
let users: [User] = try codableFiles.load(withFileName: fileName)Delete a file.
try codableFiles.deleteFile(withFileName: fileName)Delete default directory.
try codableFiles.deleteDirectory()Delete a custom directory.
let customDir = CodableFilesDirectory.directoryName("MyFolder")
try codableFiles.deleteDirectory(directoryName: customDir)Copy a file from Bundle to documents directory.
let pathURL = try codableFiles.copyFileFromBundle(bundle: .main, fileName: fileName)Save and load using a custom directory.
let customDir = CodableFilesDirectory.directoryName("UserData")
try codableFiles.save(user, withFileName: fileName, atDirectory: customDir)
let loaded: User = try codableFiles.load(withFileName: fileName, atDirectory: customDir)Check if a file exists.
let exists = try codableFiles.isInDirectory(fileName: fileName)Get a file path.
let fileURL: URL? = try codableFiles.getFilePath(forFileName: fileName)Change the default directory name.
codableFiles.setDefaultDirectoryName(directoryName: "MyAppData")
print(codableFiles.writeDirectoryName) // "MyAppData"Recommended way to handle errors.
do {
let user: User = try codableFiles.load(withFileName: fileName)
} catch {
print("CodableFiles - Error: \(error.localizedDescription)")
}AppBundle is read-only, so you cannot write to it programmatically. That's the reason we use the Documents Directory for read & write operations. Read more: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.
Once you have your Swift package set up, adding CodableFiles as a dependency is as easy as adding it to the dependencies value of your Package.swift.
dependencies: [
.package(url: "https://github.com/egzonpllana/CodableFiles.git", from: "2.0.0")
]To add CodableFiles as a dependency to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL:
https://github.com/egzonpllana/CodableFiles.git
Note: As of v2.0.0, CocoaPods is no longer supported. Please migrate to Swift Package Manager, which is Apple's official dependency management solution. The last CocoaPods-compatible version is
1.1.2.
So, why was this made? While I was working on a project to provide mocked URL sessions with dynamic JSON data, I found that we can have these data saved in a file in Document Directory or loaded from Bundle so later we can update, read or delete based on our app needs. The objects that have to be saved or loaded must conform to the Codable protocol. So, I made Codable Files that make it possible to work with JSON data quicker, in an expressive way.
Feel free to open an issue, or find me @egzonpllana on LinkedIn.
