FileSystem
FileSystem is a simple and concise protocol orientated framework for dealing with the file system on iOS, tvOS, watchOS and macOS.
For safety and consistency all of the Item based APIs are implemented as functions that can throw an error. This is predominately driven by the fact the other processes outside of an app's control can modify the file system at any time, coupled with the fact that Swift 3 has no concept of properties that can throw an error.
Types
The main Types in FileSystem are listed below with protocols being emphasised:
- Path
- PathRepresentable
- Parent
- Subitem
- Copyable
- CopyableSubitem
- Moveable
- MoveableSubitem
- Renameable
- Removable
- Trashable
- Linkable
- SymbolicLinkable
- Aliasable
- FileHandleConvertible
- FileWrapperConvertible
- Item
- File
- RegularFile
- SymbolicLink
- AliasFile
- Directory
- Volume
Path
Path is used to represent a location on disk, meaning that you no longer have to keep switching between String and URL.
Path is RawRepresentable by a String, so can it be initialised using the default initialiser (which will return nil if the rawValue is invalid):
let path = Path(rawValue: "/")As this is so common you can omit the rawValue parameter label:
let path = Path("/")Path adopts ExpressibleByStringLiteral, meaning that when the type can be inferred by the compiler you can omit the initialiser altogether:
let path: Path = "/"As mentioned before the current APIs use a mixture of String and URL representations, so to make things easier Path can also be initialised with a file URL:
let path = Path(url)Path has various APIs for accessing its components:
public var components: [String]
public var lastComponent: String
public var componentsToDisplay: [String]?In addition to creating new paths based on its existing components:
public func appendingComponent(_ component: String) -> Path
public func deletingLastComponent() -> Path
public func replacingLastComponent(with component: String) -> PathThere is an API to access the path’s extension:
public var `extension`: StringThere are APIs to resolve and standardise a Path:
public var resolved: Path
public var standardized: PathIn addition to seeing if a Path already exists:
public var exists: BoolTo access the Item at a given path you can use the item property:
public var item: Item?PathRepresentable
PathRepresentable can be adopted by anything that can be represented by a Path.
var path: Path { get }
init?(path: Path)The initializer should return nil if the PathRepresentable does not exist or if it is not of the correct type.
Item
Item is the base protocol for all file system items that can be represented by Path. Item adopts PathRepresentable, CustomStringConvertible and CustomDebugStringConvertible.
Item adds an additonal initailzer that doesn't the check to see if the Item exists at the given Path, which is used internally by the FileSystem framework for efficiency (e.g. when a valid path representation has been returned by a system API):
init(_ path: Path)It also requires that the path property can be set:
var path: Path { get set }Item has the following APIs:
public func exists() throws -> Bool
public func localizedName() throws -> String
public func isReadable() throws -> Bool
public func isWritable() throws -> Bool
public func isExecutable() throws -> Bool
public func isHidden() throws -> Bool
public func isPackage() throws -> Bool
public func isApplication() throws -> Bool
public func isAliasFile() throws -> Bool
public func isSymbolicLink() throws -> Bool
public func creationDate() throws -> Date
public func contentAccessDate() throws -> Date
public func contentModificationDate() throws -> Date
public func attributeModificationDate() throws -> Date
public func attributes() throws -> [FileAttributeKey: Any]
public func setAttributes(_ attributes: [FileAttributeKey: Any]) throwsParent
Parent protocol for an Item that can be a parent of another Item.
The Parent protocol provides APIs for accessing its subitems:
func subitems() throws -> [Subitem]
func isEmpty() throws -> Bool
func contains(_ subitem: Subitem) throws -> BoolSubitem
Subitem protocol for an Item that can be a subitem of another Item.
The Subitem protocol provides APIs to access its root volume and parent directory:
func rootVolume() throws -> Volume
func parentDirectory() throws -> Directory?Copyable
Copyable protocol for an Item that can be a copied.
func copy(to path: Path) throws -> SelfCopyableSubitem
CopyableSubitem protocol for an Item that adopts Copyable and Subitem.
func copy(into parent: Parent) throws -> SelfMoveable
Moveable protocol for an Item that can be moved to another Path.
mutating func move(to path: Path) throwsMoveableSubitem
MoveableSubitem protocol for an Item that adopts Moveable and Subitem.
mutating func move(into parent: Parent) throwsRenameable
Renameable protocol for an Item that can be renamed.
mutating func rename(to name: String) throwsRemoveable
Renameable protocol for an Item that can be removed, note that the item is removed instantly.
func remove() throwsTrashable
Trashable protocol for an Item that can be trashed.
On macOS the protocol has has the following APIs:
mutating func trash() throwsLinkable
Linkable protocol for an Item that can be hard linked to a Path.
func link(to path: Path) throws -> LinkableSymbolicLinkable
SymbolicLinkable protocol for an Item that can be symbolic linked to a Path.
func symbolicLink(to path: Path) throws -> SymbolicLinkAliasable
Aliasable protocol for an Item that can be aliased.
FileHandleConvertible
FileHandleConvertible protocol for an Item that can be converted into a FileHandle for either reading, writing or updating (both reading and writing).
func fileHandleForReading() throws -> FileHandle
func fileHandleForWriting() throws -> FileHandle
func fileHandleForUpdating() throws -> FileHandleFileWrapperConvertible
FileWrapperConvertible protocol for an Item that can be converted into a FileWrapper.
func fileWrapper() throws -> FileWrapperFile
File is the base protocol for a single file and adopts Item, Subitem, Copyable, CopyableSubitem, Moveable, MoveableSubitem, Renameable, Removeable, Trashable, Linkable, SymbolicLinkable and Aliasable.
File has the following APIs:
public func isContentEqual(to file: Self) -> BoolRegularFile
RegularFile is a struct that adopts File, FileHandleConvertible and FileWrapperConvertible, and is used to represent a regular file i.e. not a symlink or alias.
RegularFile has the following API:
public func size() throws -> IntSymbolicLink
SymbolicLink is a struct that adopts File and FileWrapperConvertible, and is used to represent a symbolic link.
SymbolicLink includes an API to retrieve its destination:
public func destination() throws -> SymbolicLinkableAliasFile
AliasFile is a struct that adopts the File protocol and is used to represent an alias file.
AliasFile includes an API to retrieve its destination:
public func destination() throws -> AliasableDirectory
Directory is a struct that adopts Item, Parent, Subitem, Copyable, CopyableSubitem, Moveable, MoveableSubitem, Renameable, Removeable, Trashable, SymbolicLinkable, Aliasable and FileWrapperConvertible.
Directory has APIs to access system directories:
public static var temporary: Directory
public static var document: Directory
public static var library: Directory
public static var caches: Directory
public static var application: Directory
public static var applicationSupport: Directory
public static var desktop: Directory
public static var downloads: Directory
public static var movies: Directory
public static var music: Directory
public static var pictures: Directory
public static var applications: [Directory]
public static var libraries: [Directory]Directory has an API to access its relationship to another Item:
public func relationship(to item: Item) throws -> FileManager.URLRelationshipIn addition to an API for creating a Directory at a Path:
static public func create(at path: Path, withIntermediateDirectories: Bool = false, attributes: [String : Any]? = nil) throws -> DirectoryThere is also an API for returning container directories:
public static func container(forSecurityApplicationGroupIdentifier groupIdentifier: String) -> Directory?Volume
Volume is a struct that adopts Item, Parent, Renameable, Linkable and SymbolicLinkable.
Volume provides an an API to access all of the mounted volumes:
public static var mounted: [Volume]In addition to APIs to access information about the Volume itself:
public func totalCapacity() throws -> Int
public func availableCapacity() throws -> Int
public func usedCapacity() throws -> Int
public func isEjectable() throws -> Bool
public func isRemovable() throws -> Bool
public func isInternal() throws -> Bool
public func isLocal() throws -> Bool
public func isReadOnly() throws -> BoolOn macOS you can also unmount the Volume:
public func unmount(withOptions options: FileManager.UnmountOptions = [], completionHandler: @escaping (Error?) -> Void)