Skip to content

Conversation

connor-ricks
Copy link

@connor-ricks connor-ricks commented Oct 8, 2025

A small PR to add an initializers for LocalizedStringResource for convenience.

Apple is pushing developers away from LocalizedStringKey and instead recommending they use LocalizedStringResource going forward.

LocalizedStringResource is the recommended type for representing and passing around localizable strings. It not only supports initialization using a string literal, but can also be provided with a comment, table name, or even a default value that's different from the string key.

There are a variety of benefits of resources over keys mentioned in Apple's docs.

SwiftUI views like Text and Button take LocalizedStringResource. While it is easy enough to call String(localized:) ourselves when using TextState, adding this initializer feels like a small amount of effort for a sizable convenience for consumers.

@mbrandonw
Copy link
Member

Hi @connor-ricks, thanks for looking into this, but I think it'd be better to add a case to enum Storage for localizedStringResource instead of eagerly stringifying into a verbatim case. That way we can hand off an honest LocalizedStringResource value to SwiftUI's APIs, which I imagine has some benefits (though let me know if I am wrong).

But to do that you would need to hold onto an Any in the case and do some runtime checking under the hood. Are you down to explore that?

@connor-ricks
Copy link
Author

Hi @connor-ricks, thanks for looking into this, but I think it'd be better to add a case to enum Storage for localizedStringResource instead of eagerly stringifying into a verbatim case. That way we can hand off an honest LocalizedStringResource value to SwiftUI's APIs, which I imagine has some benefits (though let me know if I am wrong).

But to do that you would need to hold onto an Any in the case and do some runtime checking under the hood. Are you down to explore that?

I can give this a stab at some point this week! I'm traveling today.

Updates LocalizedStringResource usage to use an Any box rather than using the string verbatim. This allows us to use the actual "correct" Text exposed by SwiftUI.

- The Any box is required given the minimum version os swift-navigation. Initializing anything else besides a resource would be a programmer error, so encapsulating it in a box allows us to fail in one place rather than having pre-conditions everywhere.

- Renames `.localized` to `.localizedStringKey` for clarity.
@connor-ricks
Copy link
Author

@mbrandonw let me know your thoughts on these changes. I wrapped things in a "box" so that all the "impossible" places were handled in one location rather than having a couple scattered across the file.

I also renamed .localized for added clarity.

// MARK: - LocalizedStringResourceBox

fileprivate struct LocalizedStringResourceBox: Equatable, Hashable, @unchecked Sendable {
let value: Any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use any Sendable here to get rid of the @unchecked Sendable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out I can't actually do this as LocalizedStringResource isn't sendable until iOS 18.

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.

3 participants