I created the FormattedString that I mentioned in a previous post. I wanted to encapsulate some basic formatting options in my own class that would use the NSAttributedString class internally. I also want to use the variadic function capability in Swift to make formatting text as simple and as readable as possible. Of course, my idea of simple and readable are probably very different from other people’s ideas. In fact, using the variadic function capability for formatting the string is possibly a terrible idea. Even if it’s not the best way to do things, it was worth the effort to learn about Swift variadic functions and to attempt this implementation.
The code above is the entire class. This FormattedString class only supports font size, font color, bolding, and italicizing. There is no way to specify a different font family. Since Swift converts variadic function arguments to an array immediately when a function is invoked, there is no way to pass variadic parameters to another function. And because I needed to let the user initialize an object with formatting data and also append formatting data, I had to create a private function to do the formatting. Both the init() function and the public append() function call the internal append() function with an array.
The most severe down-side to this method of formatting a string is the lack of self-documentation in the code. Although it will be obvious when a string of text or a color is passed to a FormattedString object, there is nothing that makes it clear that a Double or Int is a font size value. There is also no way to let the caller provide labels for variadic function parameters. My preference would be for Swift to allow a function to use a wildcard label of some sort and then let the caller add a label to the call that is any label they feel is appropriate. But that syntax would only make sense for the type of code used in this class – it would not be useful in any other situation I can think of.
The line of code above will set the text of a UILabel to an NSAttributedString. The NSAttributedString named attributedString is a member of the FormattedString class. I think I could have created a conversion function somewhere but this way seems self documenting and keeps the code understandable enough.
It seems fair to mention alternatives to this way of doing things. I could have written the init() and append() functions to accepts a String followed by values for the font options. Those values would have defaults so the caller could just call the functions with parameter that they want to set. That’s not enough though because the caller might want to skip some font formatting values; The code would need to provide the functions in 24 different variations so the caller could set any one, two, or three options in any order. A better alternative is to use optional parameters and let the caller pass in “nil” for the formatting options they don’t want. This is ugly because the “nil” values would have the same meaning as the parameter not being set at all but with more code to read. The best solution would be for Swift to allow a function to be called with the parameters in any order. I see no reason why the compiler could not handle this since the labels would tell the compiler at compile time how to rearrange the parameters for the actual call. Until Swift is improved (or changed for the worse;), my implementation is no worse than any other solution for allowing a variable set of parameters in a variable order.