Introduction
An application often needs to create file in and read file from a SearchPathDirectory
e.g. current users Document directory. For this, we need to create a URL with file path pointing to the desired file.
However, At present there is no straight forward way to create such a URL in these search path directories.
This proposal is to add a function to FileManager to create a file path url.
Motivation: The Problem
Say, we want to save data
to a document directory in a file named "data.dt".
At present, this URL can be created in the following way:
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileURL = URL(fileURLWithPath: "data.dt", relativeTo: documentDirectory)
// or
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileURL = documentDirectory.appendingPathComponent("data.dt")
Probably this could be made more "friendly" :)
Proposed Solution
We can add a method to FileManager class with following signature. e.g.
func url(filePath: String,
for directory: FileManager.SearchPathDirectory,
in domainMask: FileManager.SearchPathDomainMask) -> URL?
Then, we can use like:
// it will give full file URL in document directory, in current user domain
FileManager.default.url(filePath: "hello.txt")
// or we can specify any search path directory and user domain mask
FileManager.default.url(filePath: "hello.txt", for: .userDirectory) // Full file path in user home directory
FileManager.default.url(filePath: "hello.txt", for: .documentDirectory, in: .userDomainMask) // pass as needed
Detailed Design:
a probable implementation could be like:
@available(macOS 10.6, iOS 4.0, *)
public func(filePath: String, in directory: FileManager.SearchPathDirectory = .documentDirectory, domain: FileManager.SearchPathDomainMask = .userDomainMask) -> URL? {
guard let directory = FileManager.default.urls(for: directory, in: domain).first else { return nil }
return directory.appendingPathComponent(filePath)
}
Source Compatibility
This change is additive only
Effect on API resilience
This change is additive only
Alternatives considers
Instead of that we could have constructor for URL like this:
let url = URL(fileName: "data.dt" in:.documentDirectory domain: .userDomainMask)
We can add a constructor to URL class as follows:
public init?(fileName: String, in directory: FileManager.SearchPathDirectory = .documentDirectory, domain: FileManager.SearchPathDomainMask = .userDomainMask) {
guard let directory = FileManager.default.urls(for: directory, in: domain).first else { return nil }
self.init(fileURLWithPath: fileName, relativeTo: directory)
}