Namespaces in Swift

To avoid naming collisions with other libraries and frameworks, an Objective-C class needs to have a unique name. That's the reason Apple uses prefixes on Objective-C classes, such as UIView, CGRect, and CALayer. Swift modules make the need for class prefixes obsolete.

Even though modules are an important step forward, they're not as flexible as many developers would want them to be. Swift currently doesn't offer a solution to namespace types and constants within modules.

A common problem I run into when working with Swift is defining constants in such a way that they are easy to understand by anyone working on the project. In Objective-C, this would look something like this. Every constant is prefixed with two or three letters to avoid naming collisions and the name of the constant describes its use in the project.

NSString * const CCAPIBaseURL = @"https://example.com/v1";
NSString * const CCAPIToken = @"sdfiug8186qf68qsdf18389qsh4niuy1";

This works fine, but it isn't pretty or easy to read. But it's still better than using string literals throughout the project.

Using Structs

Even though Swift doesn't support namespaces within modules, there are a few viable solutions to this problem. The first solution uses structs to create namespaces and it looks something like this.

struct API {

    static let BaseURL = "https://example.com/v1/"
    static let Token = "sdfiug8186qf68qsdf18389qsh4niuy1"

}

We define a struct, API, and declare one or more static constant properties. I believe this solution was first coined by Jesse Squires. It works great, it's easy to adopt, and the syntax to access the constants is intuitive and easy to read.

import Foundation

if let url = URL(string: API.BaseURL) {
    ...
}

There's one unwanted side effect. The API struct can be instantiated. While this isn't a problem in itself, it may confuse other developers working on the project. You could declare the initializer of the API struct private, making it inaccessible to other parts of the project.

struct API {

    private init() {}

    static let BaseURL = "https://example.com/v1/"
    static let Token = "sdfiug8186qf68qsdf18389qsh4niuy1"

}

Initializing a Structure Without Accessible Initializers

Using Enums

Another solution was proposed by Joseph Lord in a discussion on Twitter and written about by Natasha Murashev. Instead of using structs, Joseph proposed to use enums without cases. An enum without cases cannot be instantiated, but it can act as a namespace.

enum API {

    static let BaseURL = "https://example.com/v1/"
    static let Token = "sdfiug8186qf68qsdf18389qsh4niuy1"

}

This solution is almost identical to the one that uses a struct. The main difference is you cannot create an instance of the API enum without having an error thrown at you.

Initializing an Enumeration Without Cases

Using enums or structs to create namespaces works very well for me. You don't need to put the constants of your project in a single enum or struct. Take a look at the following, more advanced, example. You have to admit that this look quite appealing, especially when compared to Objective-C.

enum API {

    static let BaseURL = "https://example.com/v1/"
    static let Token = "sdfiug8186qf68qsdf18389qsh4niuy1"

}

extension UserDefaults {

    enum Keys {

        static let CurrentVersion = "currentVersion"
        static let DarkModeEnabled = "darkModeEnabled"

    }

}

We create an extension for the UserDefaults class and define a nested enum, Keys. The resulting API is easy to read and clearly describes the meaning of the CurrentVersion constant.

// Update User Defaults
let userDefaults = UserDefaults.standard
userDefaults.set(1.0, forKey: UserDefaults.Keys.CurrentVersion)

Conclusion

This pattern may look a bit odd at first, but it works very well. Not only does it make working with constants easier, it's a simple pattern that's very easy to pick up.