Need to have same string literal to occur in source twice, what's the best DRY way to do it?

I need my source code to be like this:

enum ImageName {
    static let personBicycle = String(localized: "person.bicycle")
}

struct ContentView: View {
    var body: some View {
        VStack {
            Image("person.bicycle")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .padding()
    }
}

The string "person.bicycle"? need to occur exactly like this twice in my source. The reason for this is that:

Image("person.bicycle")

it'll look for a localizable version of the string "person.bicycle". But unfortunately, Xcode Export localization do not extract this string from this code. It'll needs to see something like this in addition to help it extract:

enum ImageName {
    static let personBicycle = String(localized: "person.bicycle")
}
1 Like

Just to confirm: you want that image localised?

I don't localise images, so will leave that for others to fill.


Here's a different idea though

I like when compiler (1) type completes image names for me (or string names / font names), (2) checks for typos in names. Also (3) I'd like to check that all static images (localised strings / fonts) used in the app are present in the app bundle, which I can do in a test function during app startup (e.g. development builds only). And (4) I don't like typing same (or similar) names twice: personBicycle plus "person.bicycle" . To achieve all this I use an enum like so:

enum ImageKey: String, CaseIterable {
    case person_bicycle
    case fugazi
    ...
}

String RawValue to not type the string myself and CaseIterable allows enumerating all cases e.g. to check all images are present.

Then it can be used as: Image(.person_bicycle) or Image(image(.person_bicycle)) or just image(.person_bicycle) or ImageKey.person_bicycle.image (I don't have a preference here) or pick your own convention.

OTOH, as you noticed you may lose something on a different front, e.g. how localisation is affected. Also if you used image name in one place in the app - now you use it in two places, so that's some overhead. And if you remove image usage you may forget to remove it from the enumeration. Some pros / some cons with this approach.

I heard there are tools around that automate this idea but I prefer doing it manually. Ideally something like this should be built into Xcode (e.g. image names are generated from asset catalog(s), unused images give compilation warning, etc. There was an attempt at that (#imageResource) although it's not ideal.

1 Like