Open Brett-Best opened 2 weeks ago
Hey! So LocalizedStringKey
has some annoying limitations, which I think that LocalizedStringResource
was supposed to resolve, but in SwiftUI, many views still lack initialisers for the newer type, which is somewhat annoying π (plus the iOS 16+ constraint).
Like you spotted, tableName
and bundle
exist on the Text
initialiser directly and are not part of LocalizedStringKey
, but also localized string arguments can only be passed in via string interpolation via LocalizedStringKey
, which means that your key must contain the interpolation placeholders as well (i.e "MyKey \(arg)"
== MyKey %@
).
It's because of these annoying limitations with SwiftUI apis prior to iOS 16 that I didn't bother adding support initially. I couldn't find a worthwhile path forward that worked around all of this π
I guess that #50 is a step forward. You can add a convenience Text
initialiser that resolves the string inside the initialiser, or write a small wrapper view that pull the Locale
out of the environment and use that when resolving the string, but none of these will be quite as convenient as using Text
+ LocalizedStringResource
unfortunately π₯
I'd need to think about it some more, but another possibility might be to ship a small supplementary library that contains a LocalizedText
type that could be used as a backwards compatible drop-in replacement to Text
for those who need to support iOS 15 π€
I've not used SwiftUI too extensively myself, so I just want to confirm that the reason why you are looking for more advanced SwiftUI support on iOS 15 is because of the way that the language should be resolved from within the SwiftUI environment rather than using the String
initialiser that would use Locale.current
? Or is there something else? Or maybe I just need to push a release that contains #50 π
Hi hope you're doing well, is there any reason for not releasing the iOS 15 support yet ? Thank you
I had been on holiday and had only returned today. Iβll do it over the weekend π
Thank you so much, hope you had good holiday π
0.2.0 has now been released with initial support for iOS 15/macOS 12 π
Please try it out, and let me know how we might be able to improve usage in SwiftUI π
I tried, it's not working i think you forgot to change the mimimum requirement version platform in the package, i tried to change it locally, but i'm getting error on the parser
The minimum platform versions in Package.swift are correct. The CLI executable doesn't support macOS 12/iOS 15, only the generated code.
If you need to use the plugin in your iOS 15 project, you should use xcstrings-tool-plugin repository, which uses a precompiled binary artefact, not the xcstrings-tool repository as that requires compiling the CLI from source.
I'd need to think about it some more, but another possibility might be to ship a small supplementary library that contains a
LocalizedText
type that could be used as a backwards compatible drop-in replacement toText
for those who need to support iOS 15 π€I've not used SwiftUI too extensively myself, so I just want to confirm that the reason why you are looking for more advanced SwiftUI support on iOS 15 is because of the way that the language should be resolved from within the SwiftUI environment rather than using the
String
initialiser that would useLocale.current
? Or is there something else? Or maybe I just need to push a release that contains #50 π
I realised that this wont quite work, because the locale
passed into the String.init(localized:defaultValue:table:bundle:locale:)
is not used liek the locale on LocalizedStringResource
.. Changing this locale only impacts the number formatting of int/float arguments, just like the old String.init(format:locale:arugments:)
initializer, which kind of sucks π
I think that basically means that there is no clean way to be able to take the locale from the SwiftUI environment and then to resolve strings in that language prior to iOS 16, unless you poke into the bundle yourself, which isn't ideal.
Hopefully I missed something though.
Hi. I'm also trying to retrofit this into an iOS15 project. I tried integrating xcstrings-tool
but when trying to pass in a string into a struct constructor, the error im getting is
Member 'regulationsLink1' in 'String' produces result of type 'String.Onboarding', but context expects 'String'
Am I missing something here?
@mylogon341 please share the code that youβre trying to use. For iOS 15, youβd need to resolve the String directly rather than passing the generated type into something like Text.
Something like this is correct usage:
String(onboarding: .regulationsLink1)
@mylogon341 please share the code that youβre trying to use. For iOS 15, youβd need to resolve the String directly rather than passing the generated type into something like Text.
Something like this is correct usage:
String(onboarding: .regulationsLink1)
Of course - yes that works as intended, thanks.
I tried thinking how to improve SwiftUI usage on iOS 15, but I am stuck. You are right that whatever we need to do will need to be done through LocalizedStringKey
(with Text
as well), but the main problem that I can't find a solution for is that with LocalizedStringKey
, the format specifiers need to make up the key through interpolation.
If you dump a LocalizedStringKey
instance, you can see that there are separate key
and arguments
properties, but I can't find a way to init a custom instance π ... Maybe there is some private API trickery that can be done, but i'm not sure.
After some digging with @Brett-Best today, I think that we are going to try with the following:
#if canImport(SwiftUI)
extension Text {
init(localizable: String.Localizable) {
if #available(macOS 13, iOS 16, tvOS 16, watchOS 9, *) {
self.init(LocalizedStringResource(localizable: localizable))
return
}
var stringInterpolation = LocalizedStringKey.StringInterpolation(
literalCapacity: 0,
interpolationCount: localizable.arguments.count
)
for argument in localizable.arguments {
switch argument {
case .int(let value):
stringInterpolation.appendInterpolation(value)
case .uint(let value):
stringInterpolation.appendInterpolation(value)
case .double(let value):
stringInterpolation.appendInterpolation(value)
case .float(let value):
stringInterpolation.appendInterpolation(value)
case .object(let value):
stringInterpolation.appendInterpolation(value)
}
}
let makeKey = LocalizedStringKey.init(stringInterpolation:)
var key = makeKey(stringInterpolation)
key.overrideKeyForLookup(using: localizable.key)
self.init(key, tableName: localizable.table, bundle: .from(description: localizable.bundle))
}
}
extension LocalizedStringKey {
mutating func overrideKeyForLookup(using key: StaticString) {
withUnsafeMutablePointer(to: &self) { pointer in
let raw = UnsafeMutableRawPointer(pointer)
let bound = raw.assumingMemoryBound(to: String.self)
bound.pointee = String(describing: key)
}
}
}
#endif
It's somewhat creative, but it will bring a Text
initialiser that will work on iOS 13+ π
I was wondering what it would take to get iOS 15 SwiftUI support.
I think it would involve needing to use
LocalizedStringKey
but not sure how that would manifest with needing to specify a bundle in aText
init for example.EDIT: Looks like https://github.com/iKenndac/localized-strings-symbols does something similar to my idea above.
Any thoughts around this?