While trying to answer this question, I found a strange behaviour.
Text(LocalizedStringKey("Hello \(Image(systemName: "globe"))"))
displays a globe, but
Text(LocalizedStringKey("Hello {world}".replacingOccurrences(of: "{world}", with: "\(Image(systemName: "globe"))")))
Text(LocalizedStringKey("Hello" + "\(Image(systemName: "globe"))"))
displays "Hello" followed by a jumble of SwiftUI's internal jargon mess.
An even more minimal example would be:
let x = "\(Image(systemName: "globe"))"
print(LocalizedStringKey.init(x))
print(LocalizedStringKey.init("\(Image(systemName: "globe"))"))
The values I'm passing to LocalizedStringKey.init
should be the same, both "\(Image(systemName: "globe"))"
, but The first prints
LocalizedStringKey(key: "%@", hasFormatting: true, arguments: [...])
and the second prints
LocalizedStringKey(key: "Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.(unknown context at $7ff91ccb3380).NamedImageProvider>)", hasFormatting: false, arguments: [])
It appears that LocalizedStringKey.init
changes its behaviour depends on whether the arguments I pass is an (interpolated) string literal or not.
As far as I can see, the two calls to LocalizedStringKey.init
are calling the same initialiser. There is only one parameter-label-less initialiser in LocalizedStringKey
, which takes a String
.
If there were also an initialiser that takes a LocalizedStringKey
, the results would be much more understandable. LocalizedStringKey
has custom string interpolation rules, and one specifically for Image
, after all. But this is the only initialiser with no parameter labels as far as I know.
It would also be somewhat understandable if the initialiser's parameter is @autoclosure () -> String
. If the expression I pass in is lazily evaluated, the method might be able to "peek inside" the closure by some means unknown to me. But the parameter isn't an auto closure.
What seems to be happening here is that the compiler is creating a LocalizedStringKey
with key
being that same pattern as the interpolation you passed in, even though the parameter is a String
!
What is actually going on here? Did I miss a hidden initialiser somewhere?