liamnichols/xcstrings-tool

Duplicate accessors generated in extensions on both `String` and `LocalizedStringResource`

Closed this issue · 0 comments

The first version of generated code was a series of static computed properties and functions on a type nested under LocalizedStringResource. It allowed us to use dot syntax to access the resources in a nice way:

Text(.localizable.myKey)
// or
String(localized: .localizable.myKey)

This was great, but since it relied on LocalizedStringResource, it relied on iOS 16+, which turned out to not be great. To improve backwards compatibility, we also added an extended type under String, and generate an initialiser so that you can do this:

String(localizable: .myKey) // note 'localizable' is the associated table name

Under the hood, we also generated LocalizedStringResource.init(localizable:), but it was kept private since we were regenerating the myKey property.

Now that I'm focusing on #60, and seeing that locking into LocalizedStringResource was a bit premature, i'm considering if it is actually worth generating all of the accessors on both String.Localizable and LocalizedStringResource.Localizable.

Instead, i'm considering to deprecate LocalizedStringResource.Localizable and instead generate the following global function:

func localizable(_ localizable: String.Localizable) -> LocalizedStringResource {
    LocalizedStringResource(localizable: localizable)
}

The aim for this is to try and maintain that nice syntax we have for accessing the constants in a nice way. For example:

- Text(.localizable.myKey)
+ Text(localizable(.myKey))

Once #60 is complete, this would really shine, because it would allow us to generate another global function that can return a LocalizedStringKey type which can be used to then obtain a LocalizedStringKey representation of String.Localizable and use it in the number of places of the SwiftUI API that don't accept LocalizedStringResource.

I'm opening an issue to track this because it would be a breaking change to the generated code so I would like to understand peoples opinions on it. I'd do it in stages across three releases:

  1. Introduce the global functions and mark the LocalizedStringResource.Localizable types as deprecated without producing a warning
  2. Update the deprecations to omit a warning
  3. Remove the LocalizedStringResource.Localizable type from the generated code