"Medium" is somehow translate to "Media" even though the locale is default "en_US" and no .strings file

Text("^[\(2) \(String(localized: "Medium"))](inflect: true)")   // 2 Media !!! why?

Console prints these when run:

**2021-12-20 10:53:40.144472-0800 LocalizeVooDooWhereMediaFrom[57504:1861217] [Inflection] The word "Medium" is ambiguous. Please annotate your strings file with part of speech info.**

**2021-12-20 10:53:40.145071-0800 LocalizeVooDooWhereMediaFrom[57504:1861217] [Foundation] The word "Medium" is ambiguous. Please annotate your strings file with part of speech info.**

I don't understand why "Medium" is translated to "Media". It seems Foundation is doing this but I don't understand why this is happening.

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("^[\(2) \(String(localized: "Medium"))](inflect: true)")   // 2 Media !!! why?

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {

@Tony_Parker Any idea why?

“Media” is the plural of “medium” in English, even though people don’t exactly think of it that way most of the time. So this seems to be working correctly.

(This is similar to asking for the plural of “datum” even though “data” can be treated as a mass noun these days, “some data”.)


Correction: “media” is a plural of “medium”.

Notably, the definition of “medium” as “an individual held to be a channel of communication between the earthly world and a world of spirits” (Merriam-Webster definition 2e) has as its plural exclusively the spelling “mediums”.


Where is this translation / pluralisation vocabulary stored in the system? I'd like to look at it. What languages it supports? Note, OP doesn't have strings file.

In “WWDC21 What’s New in Foundation”: inflection is supported in English and Spanish.

The feature is called “Automatic Grammar Agreement”. I think it’s computed automatically by Foundation. (I don't think it's simple mapping, it done by some algorithm.)

Edit: At 30:50 "the Automatic Grammar Engine fix up the rest"

Text("^[\(2) \(String(localized: "forum"))](inflect: true)")   // 2 forums

What if I want "2 fora" instead of "2 forums"

The console message say:

Please annotate your strings file with part of speech info.**

There must be some way to tell it to use "mediums" for "medium" (for a person), "fora" for "forums"?

Is this something customisable via ".stringsdict" file?

PS. "fora" is something 99+% people won't understand as "forums" is the norm.

According to this sample project:

In some languages, an app may need to provide part-of-speech information to the inflection engine. This happens in English, where the words “sandwich” and “juice” are both a noun and a verb. In Spanish, the food size terms “grande” and “enorme” can be used as both adjectives and nouns. The inflection engine logs a warning when it encounters this type of ambiguity. To clarify intent, the inflection engine accepts a grammar markup that wraps the substitution with the syntax ^[…](morphology: {…}) and provides part-of-speech information. The following entry from the English strings file shows an example of this disambiguation:

"Add ^[%lld %@ %@](inflect: true) to your order" = "Add ^[%lld %@ ^[%@](morphology: { partOfSpeech: \"noun\" })](inflect: true) to your order";

I'm just using this as an example to ask how to force inflection to use equally valid alternative spelling.

There is inflectionAlternative value you can provide:

Text("^[\(2) \(String(localized: "Cactus"))](inflect: true, inflectionAlternative: 'Cactuses')")   // 2 Cacti

It's still Cati. I need to go watch the presentation to see what it does.

Edit: inflectionAlternative is for when "term of address (Feminine, Masculine or Neuter setting is unknown, not for pluralization)

Aha! Morphology, there is so much going on with this:

public enum InflectionRule {

    case automatic

    case explicit(Morphology)

    public init(morphology: Morphology)

Morphology has: GrammaticalGender, PartOfSpeech, GrammaticalNumber :thinking:

Maybe Morphology GrammaticalNumber is how to tell it to use which plural spelling?

Here is how to ad-hoc specify this in source code:

Text("^[\(2) ^[\(String(localized: "medium"))](morphology: { partOfSpeech: \"noun\" })](inflect: true)")   // 2 media b/c automatic grammar agreement

from the sample code:

Interestingly it doesn't change "pequeño" to "pequeña" for "ensalada". Although it changes from "1 ensalada pequeño" to "2 ensaladas pequeños". Bug? Tested with Xcode 13.2.1, iOS 15.2.

Don't know why that sample code didn't work as advertised out of the box, but I managed to get a minimal sample app working as intended:

struct ContentView: View {
    var body: some View {
        let word = "ensalada"
        let small = String(localized: "small")
        let locKey: LocalizedStringKey = "^[\(word) \(small)](inflect: true)"
        let locString = String(localized: "^[\(word) \(small)](inflect: true)")
        VStack {

with this in the Spanish localizable strings file:

"small" = "pequeño";

This correctly shows ensalada pequeña on screen, changing pequeño appropriately to match feminine ensalada. As for the second string (locString) it shows this: ^[ensalada pequeño](inflect: true) which is not exactly what I was hoping for: I was after the string ensalada pequeña as it is shown in UI. How do I get that string? The idea is to see the resulting string containing "pequeño" / pequeña / "pequeños" as a round about way of getting word's gender (I don't see string's gender directly available in the API).

Morphology has a GrammaticalGender enum plus two other enum's. I don't know how it's supposed to be used, whether it can be specified in the inflection json expression, or could it be used only by the OS to indicate the ueer's "Term of Address"?

I wish to know if this "Automatic Grammar Engine" can be control so that we can tell it e.g. "Medium" is a person, not a size so it should pluralize it as "Mediums", not "Media" as @Nevin said above.

Terms of Service

Privacy Policy

Cookie Policy