FileSmith: Type-safe file handling in Swift

Dealing with file paths in Swift is cumbersome. Using only the standard library leaves us with Strings, which we can join together or split by /. It gets the job done but it’s not pretty, and we need a separate type so our methods can accept file paths exclusively and not just any old String. Foundation gives us this in NSURL/URL, which are also used for internet URLs so their method names are very general and long. E.g. url.deletingPathExtension().lastPathComponent to return the file name without the extension.

The Swift Package Manager has separate types for absolute paths and relative paths, because in their opinion these are fundamentally different. I can see their point, but I think it should be up to the callers of an API and not the creators whether to use absolute or relative paths.

The best alternative I’ve been able to find is JohnSundell/Files, because it gets an important thing right: it differentiates between files and directories. These are fundamentally different things (even though the internal representation of their paths are identical) and should have different types with different functionalities. You can’t read from or write to a directory itself, nor can you add a directory to a file.

What I am looking for however has separate types not only for files and folders, but also for paths (which may or may not exist) and filesystem items (which do), and for files you just want to read from and not change and files you want to write to, rename, move and/or delete. Because filesystem access, maybe more than any other task solved by programming, has the potential to irrevocably mess things up. And one way to prevent this is extra type safety, leading to fewer programmer errors.

So I made the FileSmith library with FilePath/DirectoryPath, ReadableFile/WritableFile and Directory.

Read More

Splitting text read piece by piece

Swift version 2.1.

In the previous post we implemented lazy splitting of collections, very useful for say splitting large texts into lines. But in SwiftShell I need the same functionality for text which is acquired piecemeal, like the output of a long-running shell command read sequentially, when needed. Because shell commands which are piped together in the terminal should get to work right away, and not just hang around waiting for the previous command to finish. Like this:

 

Both scripts start at the same time. The left one uses the functionality implemented below, while the right one reads the entire input into a string first, and therefore has to wait for the ‘linemaker’ command to finish before doing any actual work.

Read More

Splitting text and collections lazily in Swift

Swift version 2.1

There are already methods for splitting collections in the Swift Standard Library, but they do all the work immediately and return the results in an array. When dealing with large strings, or streams of text, I find it better to do the work lazily, when needed. The overall performance is not necessarily better, but it is smoother, as you get the first results immediately instead of having to wait a little while and then get everything at once. And memory usage is lower, no need to store everything in an array first.

Read More

Swift: mixing default values and variadic parameters.

Update:

As of Xcode 7 beta 6, Swift no longer requires variadic parameters to be last in the function definition. Also argument labels are no longer required when combined with parameters with default values. So this all works fine now:

The rest of this post is deprecated.

Read More