/// App directories and their associated URLs
enum AppDirectory: String, CaseIterable {
// UserFiles: models, loras, embeddings, etc.
case userFiles = "UserFiles"
case models = "UserFiles/Models"
case coreMl = "UserFiles/Models/CoreML"
case python = "UserFiles/Models/Python"
// UserData: local database, saved prompt media, etc.
case userData = "UserData"
case promptMedia = "UserData/PromptMedia"
}
extension AppDirectory {
/// `URL` to the AppDirectory case (if it exists)
var url: URL? {
guard let appSupportUrl = Constants.FileStructure.AppSupportUrl else {
Debug.log("Error: Unable to find Application Support directory.")
return nil
}
let baseFolderUrl = appSupportUrl.appendingPathComponent(Constants.FileStructure.AppSupportFolderName)
return baseFolderUrl.appendingPathComponent(self.rawValue)
}
}
AppFileStructure Setup
/// Core app file-folder structure setup and configuration.
struct AppFileStructure {
/// Attempts to ensure that the required directory structure for the application exists.
/// Calls the completion handler with an error and the URL of the directory that failed to be created, if applicable.
///
/// ## Usage
/// ```swift
/// FileUtility.AppFileStructure.setup { error, failedUrl in
/// if let error = error, let failedUrl = failedUrl {
/// print("Failed to create directory at \(failedUrl): \(error)")
/// } else if let error = error {
/// print("Error: \(error)")
/// } else {
/// print("Success")
/// }
/// ```
static func setup(completion: @escaping (Error?, URL?) -> Void) {
for directoryPath in AppDirectory.allCases {
guard let directoryUrl = directoryPath.url else {
completion(FileUtilityError.urlConstructionFailed, nil)
return
}
do {
try FileUtility.ensureDirectoryExists(at: directoryUrl)
} catch {
completion(error, directoryUrl)
return
}
}
// indicate success if all directories were ensured without errors
completion(nil, nil)
}
}
ensureDirectoryExists(at url:)
extension FileStructure {
/// Ensures a directory exists at the specified URL, throwing an error if creation fails.
///
/// - If the directory exists: return the URL to said directory
/// - If the directory does not exist: create the directory and return the URL to the newly created directory
///
/// # Usage
/// ```swift
/// do {
/// try FileUtility.ensureDirectoryExists(at: directoryUrl)
/// } catch {
/// completion(error, directoryUrl)
/// }
/// ```
static func ensureDirectoryExists(at url: URL) throws {
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: url.path) {
do {
try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
} catch {
throw FileUtilityError.directoryCreationFailed(url: url, underlyingError: error)
}
}
}
}
For generalized implementation, see: https://gist.github.com/buzsh/8d8a9a55b63f129e564265fa44c21892
AppFileStructure Setup
ensureDirectoryExists(at url:)