Mike Ash has a great Friday Q&A on namespaced constants and functions in C. It is a powerful and elegant technique to avoid using #define and verbose Objective-C prefixes. Although Swift types are namespaced by their module, we can still benefit from implementing this pattern with struct and enum types. I’ve been experimenting with this approach for constants in Swift and it has been incredibly useful.

Update 23 July 2015

Inspired by this post, Lee Morgan has written a build script that generates a Swift source file based on Xcode assets. Checkout the repo AutoAssets on GitHub. Thanks Lee!

Icon image assets

We are all familiar with handling assets, particularly icons, using the UIImage(named:) API. And since iOS 7, many icons have two distinct visual states — lined and filled, or normal and selected. Thus, we find ourselves with two versions of each icon, for example UIImage(named:"music") and UIImage(named:"music-selected").

iOS Tab Bar

iOS Tab Bar, iOS Human Interface Guidelines / Source

In the past, we strove to avoid stringly-typed Objective-C in Cocoa by creating constants or categories. But rather than apply these same techniques in Swift with an extension, we can do something more sophisticated.

enum Icon: String {
    case Music
    case Movies
    case TVShows
    case Search
    case More

    func image(selected selected: Bool = false) -> UIImage {
        return UIImage(named: selected ? self.rawValue + "-selected" : self.rawValue)!
    }
}

// Usage
let icon = Icon.Music.image() // "music" icon
let iconSelected = Icon.Music.image(selected: true) // "music-selected" icon

In this example, we are using the new default enum naming for enums with a string raw type. This alone makes a huge difference — no explicit, hard-coded strings at all! We now have constants for all of our icon names, and the image(selected:) method will return the correct UIImage.

You may be thinking that we could implement an extension on UIImage instead. But the goal here is proper namespacing, which makes our code easier to read and easier to write. With an extension, we are essentially in the UIImage namespace and I would argue that this functionality is not really appropriate to add to the UIImage class globally. By creating a new type, we create our own namespace. We immediately know we are dealing with icon assets when reading and writing code. We can get precise code-completion suggestions from our editor without having to remember what kind of naming conventions our teammate used for the new methods on UIImage — was it musicIcon and musicSelectedIcon, or iconMusic and iconMusicSelected? Instead, we can simply begin typing Icon. and let the editor tell us what icons are available.

Custom colors

Another common use case for constants, or a Swift extension are for the custom colors in an app. It would be nice to be able to use an enum in this scenario, but an enum raw value type must be a value type — sorry UIColor. Alternatively, we can use structs and nested structs.

struct ColorPalette {
    static let Red = UIColor(red: 1.0, green: 0.1491, blue: 0.0, alpha: 1.0)
    static let Green = UIColor(red: 0.0, green: 0.5628, blue: 0.3188, alpha: 1.0)
    static let Blue = UIColor(red: 0.0, green: 0.3285, blue: 0.5749, alpha: 1.0)

    struct Gray {
        static let Light = UIColor(white: 0.8374, alpha: 1.0)
        static let Medium = UIColor(white: 0.4756, alpha: 1.0)
        static let Dark = UIColor(white: 0.2605, alpha: 1.0)
    }
}

// Usage
let red = ColorPalette.Red
let darkGray = ColorPalette.Gray.Dark

Again, we should not add our custom colors to UIColor globally via an extension. For colors, using an extension presents even more challenges regarding naming. For example if you have a custom red color, you cannot name the method redColor() because UIColor already defines this class method. Do you name your method red()? That’s kind of awkward. Do you prefix the method name like you would in Objective-C, jsq_redColor()? That’s more awkward in Swift. Given light and dark versions of colors, do you use darkPurple(), or purpleDark()? If you have many dark and light variants, it might be better to use the {colorName}{variant} naming convention. Regardless, everyone on your team will have different opinions on naming — and they will all be great!

Luckily we can avoid the naming wars (hopefully). Using nested structs gives us our own namespace with much richer semantics, avoids naming collisions with UIColor, and provides precise code-completion from our editor.

Storyboards and beyond

What is most interesting here is realizing how extensions can limit our design space. (And the same applies to categories in Objective-C.) It is not hard to imagine how we could apply these techniques with regard to other resources in our apps: storyboards, xibs, or sound effects. You could even nest enums inside of structs, or enums inside of enums. So far, I’ve found this pattern of namespaced constants to be extremely useful.

Let me know what you think! You can find me on Twitter.

Note: There have been some attempts to automate something similar to what I have described, like swiftrsrc and Natalie, but not exactly. Some of the deeper nesting might be difficult to automate, but I have yet to try this.