Don’t use Swift enums to contain magic strings!

At first glance, using a Swift enum with a raw type of String seems to be a great way to package (or, if you like, enumerate) magic strings used by things like Notifications:

enum NotificationNames: String {
case UserDataChanged: "UserDataChangedNotificationName"
case ReceivedAlert: "ReceivedAlertNotificationName"
case PeanutButterJellyTime: "ItsPeanutButterJellyTimeNotificationName"
}

However, this is a poor application of the Swift enum for the following reason: you are not interested in the enum case, only its raw value. Any place you want to use the magic string in your code you’re forced into fully qualifying the enum case (because the argument type is a string, not the type of your enum) and then accessing the rawValue property.

A better approach is to use a Swift struct with static constant string members defining the magic strings:

struct NotificationNames {
static let userDataChanged = "UserDataChangedNotificationName"
static let receivedAlert = "ReceivedAlertNotificationName"
static let peanutButterJellyTime = "ItsPeanutButterJellyTimeNotificationName"
}

The look is very similar to an enum, but in practice it ends up being shorter and cleaner to use:

// Using the enum:
NSNotificationCenter.defaultCenter().postNotificationName(NotificationNames.UserDataChanged.rawValue, object:nil)
// Using the struct
NSNotificationCenter.defaultCenter().postNotificationName(NotificationNames.userDataChanged, object:nil)
// If you need switching, remember that Swift can switch on just about any comparison type:
func handleNotification(note: NSNotification) {
switch note.name {
case NotificationNames.userDataChanged: print("User data changed!")
case NotificationNames.receivedAlert: print("WHAT!? An alert!")
case NotificationNames.peanutButterJellyTime: print("Where ya at? Where ya at? Where ya at?")
default: print("I have no idea what's going on.")
}
}
view raw Usage.swift hosted with ❤ by GitHub

Now, this argument is moot if you have a situation where methods in your classes take your enum type as an argument and use the rawValue at some point internally, but for things like userInfo dictionary keys, user defaults keys, notification names, segue names, etc. you are better off with the struct approach, since the string is all you’re interested in.

2015-12-16 Addendum:
As with any advice on using Swift, this should not be viewed as an Immutable Truth of the Universe™. There are still situations when an enum would be a perfectly reasonable container for your strings: namely, when you have a model built around the use of the enums and not just the strings they contain.