Strings Catalog (.xcstrings) plural rules without format (Xcode 15)

In stringsdict it was possible to define a format separately from the translation so you could do something like "n_days" which you could pass in an integer and it would return you only "Day" or "Days" without the actual value in it. And it's work great.

But now with the strings catalog it seems like the format specifier HAS to be in the value, otherwise it's not recognized. Is there now no way to pluralize anything without having the actual value inside the translation?

Cannot infer format specifier for string group because no numerical specifiers were found (en: %d.n_hours)
Answered by Systems Engineer in 764475022

Hi,

Stringsdict and String Catalog Plural Variants are not suited for a string that has plurality but no number associated with that plural.
This would do the right thing in English, but many languages would have issues.
The plural rules are different between number-based plurals (one, two, few many, other) and non-number-based plurals (1, 2+).

It’s recommended here to have 2 different plain strings, controlled by if count == 1 { … } else { … }.

More information in this session at the time linked: https://developer.apple.com/wwdc21/10221?time=1330

Accepted Answer

Hi,

Stringsdict and String Catalog Plural Variants are not suited for a string that has plurality but no number associated with that plural.
This would do the right thing in English, but many languages would have issues.
The plural rules are different between number-based plurals (one, two, few many, other) and non-number-based plurals (1, 2+).

It’s recommended here to have 2 different plain strings, controlled by if count == 1 { … } else { … }.

More information in this session at the time linked: https://developer.apple.com/wwdc21/10221?time=1330

Hi, I have had the same problem you can achieve a string without a numerical specifier when editing the source code of the xcstrings file.

  1. right click .xcstrings > Open As > Source Code
  2. add this to strings object and edit this as your want:
"%lld day" : {
      "localizations" : {
        "de" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%#@day@"
          },
          "substitutions" : {
            "day" : {
              "formatSpecifier" : "lld",
              "variations" : {
                "plural" : {
                  "one" : {
                    "stringUnit" : {
                      "state" : "translated",
                      "value" : "Tag"
                    }
                  },
                  "other" : {
                    "stringUnit" : {
                      "state" : "translated",
                      "value" : "Tage"
                    }
                  }
                }
              }
            }
          }
        },
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "%#@day@"
          },
          "substitutions" : {
            "day" : {
              "formatSpecifier" : "lld",
              "variations" : {
                "plural" : {
                  "one" : {
                    "stringUnit" : {
                      "state" : "translated",
                      "value" : "day"
                    }
                  },
                  "other" : {
                    "stringUnit" : {
                      "state" : "translated",
                      "value" : "days"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },

note: %lld day is translated in German

Its sad that we need to this every time manual by adding it to the source code.

It seems that xcstrings not support pluralization without number.

2 different plain strings, controlled by if count == 1 { … } else { … } sounds like kind of pornography.

Now I found only one way - to use legacy stringsdict file.

@Systems Engineer given your response, could you please provide clarity on how are we to handle AppIntents.AppEntity.typeDisplayRepresentation?

The AppIntents framework documents TypeDisplayRepresentation's properties name and numericFormat saying to use a .stringsdict file and shows name being a plural with no number. You can see it in the documentation here:

https://developer.apple.com/documentation/appintents/typedisplayrepresentation/numericformat

In fact, if you look at Apple's own AppIntents sample code: https://developer.apple.com/documentation/appintents/acceleratingappinteractionswithappintents you will see that despite using String Catalogs for everything else in the project, the strings used in the TypeDisplayRepresentation of the sample's AppEntitys are the exception by going into a .stringsdict (I imagine because Xcode's Strings Catalog won't permit it).

I'm curious as to the discrepancy and how to resolve it. If xcstrings and stringsdict are both not suitable for the no-number plurality case well… what are we to do here? The suggested workaround of code logic (e.g. if count == 1) isn't going to work (typeDisplayRepresentation must have a compile-time static value and cannot be computed or dynamic).

I guess for now I can keep using a .stringsdict file for these particular strings. But it seems there's a fundamental disconnect in Apple's official documentation and guidance: that you can't put numberless plurals into .xcstrings or .stringsdict files, and that you must provide a numberless plural for the TypeDisplayRepresentation.name (which ultimately must go into an .xcstrings or .stringsdict file).

What am I missing here?

Thank you for the insights.

Strings Catalog (.xcstrings) plural rules without format (Xcode 15)
 
 
Q