Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add customisation point for replacing NSLocalizedString implementation #841

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

liamnichols
Copy link

Hello 👋 We've used R.swift for years now in our project and I'm currently looking at migrating from 5.x to 7.x since we want to migrate our project to SPM in the near future.

In our project, we don't rely on the NSLocalizedString method for two reasons:

  1. Our app uses a custom language selected by the user
  2. We provide a more granular fallback on a per-phrase basis if the requested phrase is missing (i.e we only provide partial translations for es_MX and our implementation can look in es_419 or es if the phrase is missing)
    • This is something that we can't currently achieve with R.string(preferredLanguages: [ ... ])

In v5 of R.swift, we were able to use our custom implementation with the R.generated.swift code by providing an overload to NSLocalizedString(_:tableName:bundle:value:comment:) in the same module of the generated R.string struct. It wasn't great, but it did the job 😄

Looking into v7 however, it's not possible for us to use a similar trick because the resolution of a localized string has now moved into the RswiftResources module and therefor our overloaded implementation of NSLocalizedString(_:tableName:bundle:value:comment:) won't be called.

I've spent a bit of time trying to come up with various alternatives. I first started trying to just reimplement RswiftResources myself but this started getting complicated and I couldn't help but feel like I was having to write a lot of code that I didn't want to. It also meant that I had to update the generated code after running rswift:

$ sed -i '' '/import RswiftResources/d' "$SCRIPT_OUTPUT_FILE_0"
$ sed -i '' -E 's/RswiftResources\.(Image|String)Resource/\1Resource/g' "$SCRIPT_OUTPUT_FILE_0"

My fallback option is to just swizzle NSLocalizedString and replace the implementation with our own however this is my least favourite option for a lot of reasons 😄 I'm also not entirely sure if it's possible to achieve it without messing up other frameworks that call to NSLocalizedString (i.e UIKit internals).

Before going with swizzling, I have one last proposed idea that is this Pull Request. In this PR, i've added a public RswiftLocalizedString global property:

public var RswiftLocalizedString = Foundation.NSLocalizedString(_:tableName:bundle:value:comment:)

By default, it calls to Foundation's NSLocalizedString method , which is what 99.99% of users will want. But it provides me with a slightly nicer way to hook in and replace the implementation without swizzling at hopefully a very minimal cost in terms of maintenance within this project 🤞.

Please do let me know what you think though. I understand that this might need some more discussion but I opened a PR rather than an Issue to hopefully provide more context of what i'm trying to achieve. I guess that another option could be to make R.swift's preferredLanguages feature more powerful but my hunch is that it wouldn't be a simple challenge.

Thanks again for everything so far!

@liamnichols
Copy link
Author

I guess that another option could be to make R.swift's preferredLanguages feature more powerful but my hunch is that it wouldn't be a simple challenge.

I'm going to have more of a look into this next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant