Lessons from Swift 1: strings, files, bundles


Obtaining the first character of a string, as a string:
firstLetter = String(theString[theString.startIndex])

If Xcode complains at you trying to append a string using +=, use instead:

Stripping leading and trailing white space from a string:
let trimmedString = string.trimmingCharacters(in: .whitespaces)
There are other options which can remove other classes of character instead of white space – see docs. However, trying to strip leading and trailing double-quotes using:
let trimmedString = string.trimmingCharacters(in: ["\""])
appears to leave the trailing quotes in place.

Dividing a string into an array of words which separate at spaces:
let theWordArray = string.components(separatedBy: " ")

Setting plain text in a text box:
textBox.stringValue = theString

Taking a plain NSString and inserting it as attributed text into a text box:
let attr = NSAttributedString(string: theString as String)

to append it, or
let attr = NSAttributedString(string: string as String)

to replace all the existing text with the new text.

Getting the system date and time as a string:
let theDate: Date = Date()
then theDate.description contains the string ready to use.

Getting the system date and time as separate strings:
let theDate: Date = Date()
let theDateStringArray = theDate.description.components(separatedBy: " ")
if (theDateStringArray.count > 1) {
textDate.stringValue = theDateStringArray[0]
textTime.stringValue = theDateStringArray[1]

Converting a string to an integer:
let theInt = Int(theString)
The snag is that this generates an error if theString contains unconvertible characters. However this is not thrown as an error, so cannot be caught using standard techniques. To make it robust, the string should be pre-parsed.

FileManager (formerly NSFileManager)

Note the title change: code referring to NSFileManager won’t work, so use FileManager instead. Initialise using:
let fileManager = FileManager.default

Browse the documentation carefully to find the right solution. For example, you can:
moveItem(at: URL, to: URL) // using URLs, or
moveItem(atPath: String, toPath: String) // using POSIX paths.

Cool calls include:
contentsEqual(atPath path1: String, andPath path2: String) // will tell you, true or false, whether two files have the same contents
attributesOfItem(atPath: path) // returns a long list of an object’s attributes
fileManager.homeDirectoryForCurrentUser.path // is the path to the current user's Home folder.

Typical call structure might be:
let fileManager = FileManager.default
do {
try fileManager.attributesOfItem(atPath: path)
} catch let error as NSError {
print("Error: \(error.domain)")

For the File Save dialog, see part 3 dealing with UI.


Obtaining the version of a bundle:
var theKey = "CFBundleShortVersionString"
var bundlePath = "/System/Library/CoreServices/XProtect.bundle"
let myBundle = Bundle.init(path: bundlePath)
let theVersion = myBundle1?.object(forInfoDictionaryKey: theKey)

Last tested on Xcode 8.2.1, Swift 3.0.2, macOS Sierra 10.12.3.