The need to "wrap" a string in a type like "NSImage.Name" can be a nuisance, but there are actually some good reasons to do this, if you take the (small) trouble to fully adopt the pattern:
1. It's a type-safety thing. You can't specify something that's not an image name to API like "image(named:). Of course, that isn't particularly safe if you just write "NSImage.Name(rawValue: "my-image")" in the call — BTW, you can actually write just "NSImage.Name("my-image")" because there're a convenience initializer for it — but there's more …
2. The NSImage.Name is a struct, so it's extensible. Instead of writing "NSImage.Name("my-image")" directly in your calls, you can extend the struct:
extension NSImage.Name {
static let myImage = NSImage.Name("my-image")
}
How does that help? Well, now you can write "image (named: .myImage)". And how does that help, especially if you only have to call it in one place? Well, …
3. If your chosen name conflicts with an existing one, you get a compilation error in your NSImage.Name extension, and know to choose a different name, preventing a hard-to-find bug. Also, …
4. If you do need to use the image name in multiple places, your extension will cause the name to be offered by autocompletion, which can be a big win for your fingers.
This might seem like overkill sometimes, but once you've absorbed the pattern it can be worth it.
One other thing. "NSImage.Name" is a struct, which means it's extensible with your own names, as above. In cases where the API has a fixed set of names for something, Apple uses an enum, to which you can't add cases. (Otherwise, using the enum is a lot like using the struct for this kind of purpose.) That's how Apple stops you from extending something that shouldn't be extended with new names.