Ruby allows developers to easily make new namespaces using the module keyword. For example, the ActiveRecord namespace contains a class called Base, like so:

module ActiveRecord
	class Base
	
	end
end

Inside the ActiveRecord module, you can refer to this class as just Base, whereas outside the module, you’d refer to it as ActiveRecord::Base. You can add multiple classes, functions, and variables to any Ruby module.

(For those that are curious, ActiveRecord::Base is ActiveRecord’s equivalent to NSManagedObject. It’s the class you subclass from to make new ORM objects.)

I want this effect in Swift. Swift has something called modules, but those are really just frameworks. I know they can give you some potential compilation speedups, but making a Swift module is pretty high ceremony and involves a lot of configuration. I just want to type some code, and isolate some classes from some other classes.

This great Natasha the Robot post from a few months ago finally gave me the tools I needed to make Swift namespaces a reality.

She used an enum with no cases (because enums with no cases crucially can’t be initialized) and added static properties to the enum to give them a fake namespace.

enum 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)
}

I want to take advantage of this syntax because I find that the features I write have a bunch of classes that all have the same prefix. For example, the authentication flow in an app might have lots of little components: AuthenticationCoordinator, AuthenticationData, AuthenticationFormView, AuthenticationFormConfiguration, AuthenticationFormField, and AuthenticationFormFieldConfiguration, as well other namespaced objects like SignupViewController and SignupView.

Some of these class names are starting to get pretty long! Since something just called FormField would pollute the global namespace, I have to tack on the “Authentication” prefix. I don’t want it to collide with any other form fields I might have in my app. If we wanted to take Natasha’s scoping pattern to the next level, we could make an Authentication enum.

enum Authentication { }

From there, we can extend it to add nested types:

extension Authentication {
	struct Data {
		let username: String
		let password: String
		//etc
	}

	class Coordinator {
		//implementation   	
	}
}

Inside the Coordinator class, we can just refer to Authentication.Data as simply Data (since they’re both inside the Authentication module). Outside the module, we’ll refer to it as Authentication.Data. This is exactly the behavior we want.

By adding one character of code (the period) for references outside the module, we get to drop a ton of characters when working with references inside the module. Further, having to add the prefix and the period explicitly will formalize all class names inside of the module. It’ll be super obvious when we’re trying to use these types from outside the module.

We can add more extensions across multiple files.

extension Authentication {
	class LoginViewController {
		//implementation   	
	}
}

A good way to use this pattern would be namespacing a view controller and its smarter view together.

enum Signup { }

//SignupViewController.swift
extension Signup {
	class ViewController {
		func loadView() {
			self.view = View()
		}
		
		//etc
	}
}

//SignupView.swift
extension Signup {
	class View {
	    //etc
	}
}

You can also nest these modules, like Natasha shows in her post.

extension Authentication {
	enum Form {
		class View {
		    
		}
	}
}

When nesting, if you want to move things to a different file, you’ll have to use a slightly different syntax:

// create the new triply-nested namespace
extension Authentication.Form {
	enum Field { }
}

// in a different file
extension Authentication.Form.Field {
	struct Data {
				
	}
				
	class View {
			
	}
}

Because Swift doesn’t allow you to use the extension keyword outside of the file scope, when nesting, you have to use the dot-syntax to access your nested namespace.

There’s one big downside to abusing an enum type like this. The protocol keyword, like the extension keyword, is limited to the file scope only, so you can’t declare any protocols inside your namespace.

It’s a bit of a heretical approach to structuring code, but many new ideas seem heretical at first. Ideally, Swift would add a module keyword. But barring that, they could make protocols work in enums and I’d be happy to use the enum trick to fake namespaces.