It seems that Xcode gets confused when there is another format specifier before a plural variable.
As shown in the screenshot, %#@VARIABLE@ %f
works fine, but an error occurs with %f %#@VARIABLE@
.
It seems that Xcode gets confused when there is another format specifier before a plural variable.
As shown in the screenshot, %#@VARIABLE@ %f
works fine, but an error occurs with %f %#@VARIABLE@
.
Hello,
This is likely because VARIABLE
is associated with argument number 1 rather than argument 2, which would mean %arg
also represents argument number 1 and is currently contradicting %f
. In this case, the error is pointing out a legitimate problem with the string that will have runtime impact.
Simply select VARIABLE
and then open the Attributes inspector. There you will find fields for the Argument Number and Format Specifier associated with that variable.
What likely happened is that you first created the variable before %f
was added to the string, so it was created with an argument number of 1. Now that you've added %f
before the variable, you can update the argument number of VARIABLE to be 2 instead using the inspector.
Note that it is intentional that the argument numbers of variables can be adjusted independently from the variable's position in the string. Otherwise, more advanced use cases such as referencing the variable in multiple places would not be supported.
Hello. Thank you for the detailed explanation. As you mentioned, I checked the Attributes inspector, but the Argument Number field is not visible.
I suspect that this field does not appear when a stringsdict
has been migrated to xcstrings
.
(For items generated by building code like LocalizedStringResource("key_1", defaultValue: "%lf %ld")
, the Argument Number field does appear.)
Fortunately, I was able to resolve the issue by manually editing the JSON and adding the argNum
field.
Alternatively, changing %arg
to %2$ld
also seems to fix the problem.
Is it intentional that the Argument Number field is not shown in certain situations?
You are right that this situation can occur when migrating a .stringsdict to a .xcstrings.
Specifically, the migrator only populates substitution argument numbers when they were previously explicitly-specified in the specifier. For example, if the original .stringsdict format string contained %1$#@VARIABLE@
instead of %#@VARIABLE@
, the argNum
would have been automatically set upon migration. The migrator does this as a safeguard to ensure that the built .stringsdict behaves identically at runtime to the original .stringsdict with regard to implicit argument numbers (which have complex rules at runtime).
The String Catalog Editor does indeed hide the argument number and format specifier columns from the variable inspector when they are missing in the file.
As you mentioned, editing the JSON or re-creating the string (or deleting it and letting it be extracted again) can get you out of this conundrum.
I see that you filed a Feedback report about this. Thank you! That will help us evaluate whether we should change any of these rules to make the experience more intuitive and easier to recover from.
If the string is in the format %1$#@VARIABLE@
, but argNum
is set to 2 — I believe this is a contradiction.
To prevent issues like this, how about removing the argNum
field entirely from the String Catalog?
In my opinion, since plural variables already have either explicit or implicit indexes within the string, it might be possible to omit argNum
altogether.