How to Display File and Directory Lists in Your iOS App

Lee young-jun
4 min readDec 15, 2023

ShowNote allows you to control file and directory lists, and in this implementation, I utilized the OS file system instead of Core Data.

Container

To access files that the app has, follow these steps:

  1. Download files using Xcode > Windows > Devices and Simulators.

2. Extract the downloaded files.

Now, you can see the files created by the app.

Documents

How can you access the directory in your app?
You can achieve this with the urls method of FileManager.

FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask).first;

While the OS and the app have many other directories, I focus only on the document directory in this article.

There could be identical directories in some cases, so the method returns a list of URLs.

You can’t access the document’s path with the app’s bundle ID or name because the path looks like this.

file:///var/mobile/Containers/Data/Application/7E2C5F35–6A09–4FF0–93DA-E5F3DB24FDA9/Documents/

children

Now, you know the path of the documents directory, how do you get a list of files and directories in the directory? We can obtain the children URLs of the directory using contentsOfDirectory.

FileManager.default.contentsOfDirectory

.skipsSubdirectoryDescendants

If you invoke contentsOfDirectory, the returned URL list contains children of children. It means if the "documents" directory has a directory "a," and "a" has a directory "a-1," the returned URL list is ["…./a", "…./a-1"].

contentsOfDirectory has a parameter, options, and one of the options is skipsSubdirectoryDescendants.

Using this option, contentsOfDirectory excludes nested children.

.skipsPackageDescendants

contentsOfDirectory also returns contents of packaged files. It will exclude packaged file's children if skipsPackageDescendants is specified.

contentsOfDirectory will exclude packaged file’s children if skipsPackageDescendants specified.

Directory

How can we know if the children are directories or not?

FileManager's fileExists provides information on whether the path is a directory or not.

FileManager.default.fileExists(atPath: self.path, isDirectory: &is_dir);

I guess isDirectory is an inout parameter, but it receives a pointer.

I won’t go into detail about UnsafeMutablePointer in this article. The usage is equal to the inout keyword case.

The parameter is a pointer, which means I have to define an Objective-C type variable. However, it’s a little weird that there is no ObjCInt or ObjCLong.

var is_dir : ObjCBool = ObjCBool.init(false);
FileManager.default.fileExists(atPath: self.path, isDirectory: &is_dir);

return is_dir.boolValue;

Create

Now that we can see children, how do we create a new directory or file?

Create directory

It is very easy to create a new directory; just call createDirectory.

The first argument at is the URL to the new directory. withIntermediateDirectories determines whether to create the middle of the directory path. The last parameter, attributes, is the property of the new directory.

FileManager.default.createDirectory(at: url, 
withIntermediateDirectories: true,
attributes: nil);

Create File

File creation doesn’t use FileManager; use Data.write. I won't delve into the details in this article.

try data.write(to: url, options: .atomic);

Copy

If you want to clone a file to another path, use copyItem.

try FileManager.default.copyItem(at: url, to: newUrl);

All you need to know is the path URL for the original file and the new file.

Delete

Remove a directory or file when it is no longer needed.

try FileManager.default.removeItem(at: <#T##URL#>)

Demo

The full source is in this example repository.

If you found this post helpful, please give it a round of applause 👏. Explore more iOS-related content in my other posts.

For additional insights and updates, check out my LinkedIn profile. Thank you for your support!

References

--

--