Swift has a rather robust file handling ability. but for those of us familiar with Xojo, the Folderitem is the method we are most familar with.
Here is a Swift class (part of a larger File handling module).
The other classes will be posted in the days to come
/*
+------------+----------------------------------------------------------------+
| Name | folderitem |
+------------+----------------------------------------------------------------+
| Type | class |
+------------+----------------------------------------------------------------+
| Properties| count isReadable parent |
| | creationDate isWriteable path |
| | displayName length URL |
| | exists modificationDate URLpath |
| | isFolder name |
+------------+----------------------------------------------------------------+
| Methods| CopyTo Delete |
| | CreateAsFolder MoveTo |
+------------+----------------------------------------------------------------+
| Functions| child item |
+------------+----------------------------------------------------------------+
*/
private var zLastError : Bool = false
private var zLastErrorCode : Int = 0
private var zLastErrorMsg : String = "OK"
/**
The FolderItem class objects represent files or folders
- Author:
R.David Sisemore
- Version:
0.1
*/
class folderitem {
private var zPath : URL
private var zFiles = [String]()
private var zNeedsRefresh : Bool = true
required init(path : URL) {
zPath=path
zNeedsRefresh=true
ThrowErrorMessage( .OK )
}
/**
The name of the *FolderItem*. Changing this name will change the name of the file or folder.
````
aFolderItem.Name = newStringValue
or
StringValue = aFolderItem.Name
````
*/
var name : String {
get { return fileMANAGER.displayName(atPath: zPath.absoluteString) }
set {
ThrowErrorMessage( .OK )
do {
let newNAME = newValue
let oldPath = zPath
let newPath = child(newNAME).URL
try fileMANAGER.moveItem(at: oldPath, to: newPath)
zPath=newPath
zNeedsRefresh=true
} catch let error as NSError {
ThrowError( .RENAME,error)
}
}
}
/// Returns the FolderItem object for the parent of this item in the file hierarchy.
var parent : folderitem { get { return folderitem(path:zPath.deletingLastPathComponent()) } }
/// The name of the FolderItem as it should be seen by the user. [readonly version of 'name']
var displayName : String { get { return name } }
/// Indicates whether or not the folder item points to a file or directory that exists.
var exists : Bool { get { return fileMANAGER.fileExists(atPath: path) } }
/// True if the FolderItem is a directory (a folder). [same as Xojo folderitem.Directory]
var isFolder : Bool { get { return fileMANAGER.isDirectoryAtPath(zPath) } }
/// True if you have permissions to write to the FolderItem.
var isWriteable : Bool { get { return fileMANAGER.isWritableFile(atPath: path) } } //zPath.absoluteString) } }
/// True if you have permissions to read from the FolderItem.
var isReadable : Bool { get { return fileMANAGER.isReadableFile(atPath: path) } } //zPath.absoluteString) } }
/// Contains the error code for the last supported operation on the FolderItem.
var lastErrorCode : Int { get { return zLastErrorCode } }
/// Contains the error message for the last supported operation on the FolderItem.
var lastErrorMessage : String { get { return zLastErrorMsg } }
/// The number of items in the FolderItem if it is a directory/folder.
var count : Int { get { refresh(); return zFiles.count } }
/// The size of the file in bytes. For directories, the size will be zero.
var length : Int {
get {
if let fileAttr = try? fileMANAGER.attributesOfItem(atPath: path),
let fileSize=fileAttr[.size] as! Int? {
return fileSize
}
return 0
}
}
/// The modification date of the FolderItem.
var modificationDate : String { get { return fileDate(.modificationDate) } }
/// The creation date of the FolderItem.
var creationDate : String { get { return fileDate(.creationDate) } }
/// The full path to the FolderItem [Xojo folderitem.NativePath]
var path : String { get { return zPath.path } }
var URLpath : String { get { return zPath.absoluteString } }
var URL : URL { get { return zPath} }
/**
Returns a FolderItem that represents a file or directory within this FolderItem with the name Name.
````
newFolderItem = FolderItem.child(Name)
````
*/
func child(_ name:String) -> folderitem {
let tempPath : URL = zPath.appendingPathComponent(name) // Destination Path in /Documents
return folderitem(path: tempPath)
}
/**
If this FolderItem is a directory, Index is an element in a one-based array of FolderItems in this directory.
````
newFolderItem = FolderItem.item(int)
````
*/
func item(_ index:Int) -> folderitem? {
refresh()
ThrowErrorMessage( .OK )
if index>=0 && index<zFiles.count {
return self.child(zFiles[index])
} else {
ThrowError( .INDEX)
return nil
}
}
func CopyTo(name:String) {
ThrowErrorMessage( .OK )
do {
let oldPath = zPath
let newPath = parent.child(name).URL
try fileMANAGER.copyItem(at: oldPath, to: newPath)
} catch let error as NSError { ThrowError( .COPY,error) }
}
func MoveTo(destination:String) {
ThrowErrorMessage( .OK )
do {
let oldPath = zPath
let newPath = parent.child(destination).URL
try fileMANAGER.moveItem(at: oldPath, to: newPath)
zPath=newPath
zNeedsRefresh=true
} catch let error as NSError { ThrowError( .MOVE,error) }
}
/// Creates a folder at the location specified by the FolderItem properties.
func CreateAsFolder() {
ThrowErrorMessage( .OK )
if fileMANAGER.fileExists(atPath: path) {
return
} // already exists
do {
try fileMANAGER.createDirectory(atPath: path,withIntermediateDirectories: false, attributes: nil)
} catch let error as NSError { ThrowError( .DIRECTORY,error) }
}
/// Deletes the file or directory specified by the FolderItem.
func Delete() {
ThrowErrorMessage( .OK )
do {
try fileMANAGER.removeItem(atPath: path)
zNeedsRefresh=true
} catch let error as NSError { ThrowError( .DELETE,error) }
}
//
// ------ P R I V A T E F U N C T I O N S ------
//
private func fileDate(_ dateID : FileAttributeKey) -> String {
if let infoAttr = try? fileMANAGER.attributesOfItem(atPath: path),
let infoDate = infoAttr[dateID] as! Date?
{
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale.current
dateFormatter.dateFormat = "dd-MMM-yyyy HH:mm"
return dateFormatter.string(from: infoDate)
}
return "<no date>"
}
private func refresh() {
if zNeedsRefresh {
do {
zFiles = try fileMANAGER.contentsOfDirectory(atPath: path)
} catch {
zFiles = []
}
if zFiles.count>0 {
zFiles.sort()
for i in(0...zFiles.count-1).reversed() {
if Left(zFiles[i],1)=="." { zFiles.remove(at: i) }
}
}
zNeedsRefresh=false
}
}
private func ThrowError(_ errCode : fileERRORS,_ error:NSError) {
ThrowErrorMessage(errCode,"\(error.localizedDescription)")
}
private func ThrowError(_ errCode : fileERRORS,errorMsg:String="") {
ThrowErrorMessage(errCode,errorMsg)
}
}