Notes: 02. Documents Directory URL
Apple’s FileManager documentation to help you familiarize with its functionality.
This course was originally recorded in April 2020. It has been reviewed and all content and materials updated as of November 2021.
You want to save data in a file, but where do files go on iOS?
The FileManager
class can help you out with that. It’s job is to help you interact with the file system and its contents. This is what this video is all about.
Due to sandboxing restrictions on iOS, only a handful of directories are available in which to store and manage your files. The user’s Document directory is a common, and appropriate place to store data. You can access this directory, or folder, directly from playgrounds, which you’ll use in the first part of this course.
In Swift, directories are represented using the URL
struct. You’ll be using FileManager
to get the Document directory URL.
Open a new blank playground and delete any code it starts with. Everything you’ll be working with for now is in the Foundation framework, so start by importing that:
import Foundation
Then, access the default FileManager
:
FileManager.default
You can make other FileManager
instances, but for most of your tasks using the default FileManager
will work just fine as all of its methods are thread-safe. If “thread-safe” doesn’t mean anything to you yet, that’s ok, just let FileManager.default
do the heavy lifting for you.
One way to find the user’s Document directory is to use FileManager
’s instance method named urls
:
FileManager.default.urls(for: <#T##FileManager.SearchPathDirectory#>, in: <#T##FileManager.SearchPathDomainMask#>)
The first argument is where you dictate that you want a documentDirectory
:
.documentDirectory
The second argument, userDomainMask
, is how you tell the FileManager
that the directory belongs to the user:
.userDomainMask
The urls
method, as its name suggests, returns an array of URLs, but there’s only one Document directory per iOS app. If you want that single URL, subscripting at the array’s only valid index, zero, will grab it for you:
[0]
The urls
method is very general-purpose, which makes it very verbose and lengthy to access the Document directory. Considering how much you’ll be using this directory, you’re going to refactor your code to make the process easier.
How about adding a computed property called documentDirectoryURL
?
var documentDirectoryURL: URL {
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
This is much better, however, if you’re actually to use this shortcut across apps, it might be more appropriate to put this inside of a FileManager
extension:
extension FileManager {
var documentDirectoryURL: URL {
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
}
Since you don’t need a specific instance of FileManager
to access this, go ahead and make the property static
:
static
Because default
is also a static property of FileManager
, you don’t need to explicitly use FileManager
in your compuer property anymore:
default.urls(
…but by not using it, you need to add backticks because default
is a Swift keyword:
`default`.urls(...)
Then you can access your newly-created property like so:
FileManager.documentDirectoryURL
A giid place for reusable code in playgrounds is the Sources folder. Hit Command+1 and click on the arrow next to the name of the playground if it’s not already expanded.
When Sources is seleced, you can hit Option+Command+N to make a new folder. Extensions
is a good name for what you need. Then you can hit Command+N, without Option, to make a new file.
Call this new file FileManager
. If your new file is already inside the Extensions
folder, fantastic, if not you can drag the file into the folder.
Notice that this new file already has Foundation imported, as you need. Go back to the playground and cut the code you wrote by making a selection and hitting Command+X:
Then, just paste it in the new FileManager file with Command+V. Go back to the playground once more and try accessing the property in your extension:
FileManager.documentdirectoryURL
Xcode’s auto-complete didn’t work, and there is an error in the playground’s Debug Area. It’s telling you that the protection level of the computed property is internal
. To get it to work outside of the FileManager.swift file you need to make the extension public
:
public
Now, your playground should be compiling as expected. As you work with FileManager
and directories, you will need to see the structure and contents of your directories and data.
An easy way to access the Document directory is to right-click, or Option-click, the file://
url that is shown on the right-side of your playground, and then selec “Open URL”:
This is the Document directory for your current playground. Neat!